2014-09-28 52 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

相關問題