Sha*_*owe 7 .net c# wpf xaml multithreading
我正在尝试为长时间运行的操作显示请等待对话框.问题是因为这是单线程,即使我告诉WaitScreen显示它永远不会.有没有办法可以更改该屏幕的可见性并立即显示?我将Cursor调用作为示例包含在内.在我调用this.Cursor之后,光标立即更新.这正是我想要的行为.
private void Button_Click(object sender, RoutedEventArgs e)
{
this.Cursor = System.Windows.Input.Cursors.Pen;
WaitScreen.Visibility = Visibility.Visible;
// Do something long here
for (Int32 i = 0; i < 100000000; i++)
{
String s = i.ToString();
}
WaitScreen.Visibility = Visibility.Collapsed;
this.Cursor = System.Windows.Input.Cursors.Arrow;
}
Run Code Online (Sandbox Code Playgroud)
WaitScreen只是一个Z-index为99的网格,我隐藏并显示.
更新:我真的不想使用后台工作者,除非我必须这样做.代码中有许多地方会发生这种启动和停止.
Ray*_*Ray 17
单线程做它真的会很痛苦,它永远不会像你想的那样工作.窗口最终会在WPF中变黑,程序将变为"无响应".
我建议使用BackgroundWorker来完成长时间运行的任务.
这并不复杂.像这样的东西会起作用.
private void DoWork(object sender, DoWorkEventArgs e)
{
//Do the long running process
}
private void WorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
//Hide your wait dialog
}
private void StartWork()
{
//Show your wait dialog
BackgroundWorker worker = new BackgroundWorker();
worker.DoWork += DoWork;
worker.RunWorkerCompleted += WorkerCompleted;
worker.RunWorkerAsync();
}
Run Code Online (Sandbox Code Playgroud)
然后,您可以查看ProgressChanged事件以显示进度(如果您愿意,请记住将WorkerReportsProgress设置为true).如果您的DoWork方法需要一个对象(在e.Argument中可用),您还可以将参数传递给RunWorkerAsync.
这确实是最简单的方法,而不是尝试单独编写线程.
Sha*_*owe 16
我找到了一个方法!感谢这个帖子.
public static void ForceUIToUpdate()
{
DispatcherFrame frame = new DispatcherFrame();
Dispatcher.CurrentDispatcher.BeginInvoke(DispatcherPriority.Render, new DispatcherOperationCallback(delegate(object parameter)
{
frame.Continue = false;
return null;
}), null);
Dispatcher.PushFrame(frame);
}
Run Code Online (Sandbox Code Playgroud)
需要在长时间运行之前调用该函数.那将强制UI线程更新.