C# 如何在“正在工作”对话框中正确调用后台线程?
应用程序的主窗口将打开一个正在进行的工作对话框,该对话框将调用后台线程。该对话框应一直显示,直到线程完成:C# 如何在“正在工作”对话框中正确调用后台线程?,c#,wpf,multithreading,C#,Wpf,Multithreading,应用程序的主窗口将打开一个正在进行的工作对话框,该对话框将调用后台线程。该对话框应一直显示,直到线程完成: var dialog = new WorkInProgressDialog(); dialog = ShowDialg; 现在的问题是在WorkInProgressDialogconstructor中的何处/如何调用线程?如果在构造函数中调用,则在线程完成之前,对话框将不可见 此外,该对话框应在线程完成后自动关闭。以下是一个希望对您有所帮助的示例。WorkinPressDialog的一些
var dialog = new WorkInProgressDialog();
dialog = ShowDialg;
现在的问题是在WorkInProgressDialog
constructor中的何处/如何调用线程?如果在构造函数中调用,则在线程完成之前,对话框将不可见
此外,该对话框应在线程完成后自动关闭。以下是一个希望对您有所帮助的示例。WorkinPressDialog的一些简单标记:
<Window x:Class="WorkInProgressExample.WorkInProgressDialog"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="WorkInProgressDialog" Height="100" Width="300" WindowStyle="None"
ResizeMode="NoResize" WindowStartupLocation="CenterScreen">
<Border BorderThickness="3" CornerRadius="5" BorderBrush="Black" Padding="10">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
<TextBlock Grid.Row="1" Name="WorkProgressTextBlock">Work in progress...</TextBlock>
<ProgressBar Grid.Row="2" Height="30" Name="WorkProgressBar"></ProgressBar>
</Grid>
</Border>
</Window>
许多选项-您可以使用
线程
,后台工作人员
或理想情况下的新任务库,例如任务.Factory.StartNew
可能的重复堆栈溢出有许多类似的问题,包括建议的重复。您应该提供显示您到目前为止所做尝试的内容,以及该代码的功能以及与您希望/期望的不同之处的精确解释。非常感谢您提供了有用的示例。只有将DialogResult设置为true,才能关闭WorkinPressDialog?没问题。否,如果将this.DialogResult
设置为false,该对话框也将关闭。不同之处在于,从显示对话框(我的示例中的最后一个代码块)的位置可以看到bool?结果将是错误的,而不是真实的。例如,您可以使用此选项指示错误情况。如果我误解了您的问题,我还调整了答案,以包括用户尝试使用ALT+F4关闭对话框时的处理。再次感谢您的帮助和扩展示例。将DialogResult设置为值(true或false)会导致WorkinPressDialog关闭,这样说是否正确?若有,原因为何?将DialogResult设置为值后是否会引发事件?正确。在内部,DialogResult
的setter检查对话框是否已经关闭,如果没有关闭,则为您调用this.Close()
。至于为什么,这只是它发展的方式。该对话框将引发关闭
事件,然后引发关闭
事件。在我的示例中,dialog.ShowDialog()
调用将一直阻塞,直到对话框关闭。
private bool _closeAuthorised = false;
public WorkInProgressDialog()
{
InitializeComponent();
WorkProgressBar.Maximum = 10;
WorkProgressBar.Minimum = 0;
Task.Factory.StartNew(() =>
{
// Do whatever processing you need to here
for (int i = 0; i < 10; i++)
{
// Any updates to the UI need to be done on the UI thread
this.Dispatcher.Invoke((Action)(() =>
{
WorkProgressBar.Value = i;
}));
Thread.Sleep(1000);
}
// Set the DialogResult and hence close, also on the UI thread
this.Dispatcher.Invoke((Action)(() =>
{
_closeAuthorised = true;
this.DialogResult = true;
}));
});
}
protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
{
// If the user uses ALT+F4 to try andclose the loading dialog, this will cancel it
if (!_closeAuthorised)
e.Cancel = true;
base.OnClosing(e);
}
var dialog = new WorkInProgressDialog();
bool? result = dialog.ShowDialog();