我尝试了一个简单的异步等待示例,其中有和没有.ConfigureAwait(false)
。
With .ConfigureAwait(false)
你可以通过调度器更新ui,如果没有调度器就不需要。
这是情况1和3在下面的代码 - 工作,我可以理解它是如何工作的。通过调度程序的动作(()=> {})冻结了用户界面
我的问题是关于情况2,我通过调度器添加 - 完全没有必要 - 刷新
Action(() => { })
。
这偶尔会冻结我的用户界面。特别是在重复调用事件处理程序之后。
任何人都可以解释为什么ui在case 2中冻结?
private void Test_Click(object sender, RoutedEventArgs e)
{
Test();
}
public async void Test()
{
Print("Start task");
// Case 1 & 2
await Task.Delay(2000);
// Case 3
await Task.Delay(2000).ConfigureAwait(false);
Print("Finished task");
}
void Print(string text)
{
// Case 1 & 2
Output.Inlines.Add(new Run(text) { Foreground = Brushes.Blue, FontWeight = FontWeights.Bold });
// Case 2 only
Output.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Background, new Action(() => { }));
// Case 3
Output.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Background,
new Action(() =>
{
Output.Inlines.Add(new Run(text) { Foreground = Brushes.Blue, FontWeight = FontWeights.Bold
}); }));
}
在调试器中暂停并查看堆栈跟踪。 – SLaks 2014-09-28 14:04:03
这不是暂停您的用户界面的“Action(()=> {})”。它是没有'ConfigureAwait(false)'的'Task.Delay(2000)'。由于它被配置为在UI线程上运行,因此您的UI线程将在未指定的时间挂起2秒。那个未指定的时间结果是情况2的运行。 – 2014-09-28 14:13:01
@RaymondChen:延迟正在等待并且根本不冻结。只有在添加空操作后才能执行。 – Gerard 2014-09-28 14:35:37