BeginInvoke(..) 方法不会阻塞调用,它只是将一条新消息放入队列以由调度程序线程处理。在您发布的代码中,您无法保证在 DoWorks 启动之前会处理背景颜色更改。
您可以降低 DoWork 调用的优先级,以确保首先更改背景:
private void Button_Click(object sender, RoutedEventArgs e)
{
grid.Background = new SolidColorBrush(Colors.Red);
Dispatcher.BeginInvoke((Action)DoWork, DispatcherPriority.ContextIdle);
}
private void DoWork()
{
Thread.Sleep(1000);
btn.Content = "Done";
}
但这并不是人类已知的最佳解决方案。
最好在单独的线程中继续使用 DoWork。上面使用线程方法的示例将如下所示:
private void Button_Click(object sender, RoutedEventArgs e)
{
grid.Background = new SolidColorBrush(Colors.Red);
Task t = new Task(DoWork);
t.Start();
}
private void DoWork()
{
Thread.Sleep(1000);
// Synchronize calls to the UI elements
Application.Current.Dispatcher.BeginInvoke((Action)(() => { btn.Content = "Done"; }));
}
只需记住将 UI 元素上的所有操作发布到 UI 线程即可。