2014-09-28 54 views
3

我尝试了一个简单的异步等待示例,其中有和没有.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 
     }); })); 
} 
+0

在调试器中暂停并查看堆栈跟踪。 – SLaks 2014-09-28 14:04:03

+3

这不是暂停您的用户界面的“Action(()=> {})”。它是没有'ConfigureAwait(false)'的'Task.Delay(2000)'。由于它被配置为在UI线程上运行,因此您的UI线程将在未指定的时间挂起2秒。那个未指定的时间结果是情况2的运行。 – 2014-09-28 14:13:01

+0

@RaymondChen:延迟正在等待并且根本不冻结。只有在添加空操作后才能执行。 – Gerard 2014-09-28 14:35:37

回答

3

这是WPF中的一个错误。

它运行一个已过滤的 GetMessage()循环(请参阅 here),其中 will hang如果消息卡在队列中并且不符合过滤器。

+0

进一步看,我的解释是错误的;它实际上并没有过滤任何东西。这仍然是WPF中的一个bug,但我不知道它为什么会挂起。 – SLaks 2014-09-28 15:24:05

+0

@hvd:是;我刚刚意识到这一点。任何想法为什么它会挂起? – SLaks 2014-09-28 15:24:40

+0

@SLaks我意识到当你看到你的评论时你才意识到。 :)不,不知道。 – hvd 2014-09-28 15:25:41

相关问题