2015-02-10 155 views
-1

中顯示一個自定義對話框窗口比方說,我有一個非常簡單的進度與IsIndeterminate=true一個長時間運行的任務

<Window x:Class="My.Controls.IndeterminateProgressDialog" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Name="Window" 
     Width="300" Height="110" ResizeMode="NoResize" Topmost="True" 
     WindowStartupLocation="CenterScreen" WindowStyle="None"> 

     <Grid>    
      <ProgressBar Width="200" Height="20" IsIndeterminate="True" /> 
     </Grid> 

</Window> 

我想這可能需要一段時間,任務過程中顯示此對話框。我不關心進度(我無法確定),我只是想通知用戶我做了一些可能需要幾秒鐘的事情。

public void GetResult() 
{ 
    string result = DoWhileShowingDialogAsync().Result; 
    //... 
} 

private async Task<string> DoWhileShowingDialogAsync() 
{ 
    var pd = new IndeterminateProgressDialog(); 

    pd.Show(); 
    string ret = await Task.Run(() => DoSomethingComplex()));    
    pd.Close(); 

    return ret; 
} 

然而,UI只是無限的凍結,任務似乎永遠不會返回。這個問題並不在DoSomethingComplex()中,如果我同步運行它,它會完成而不會出現問題。我很確定這是因爲我誤解了某些等待/異步的東西,有人能指引我朝着正確的方向嗎?

+0

你怎麼稱呼DoWhileShowingDialogAsync? – usr 2015-02-10 14:33:56

+0

@usr在上面添加了它。 – Lennart 2015-02-10 14:35:53

回答

3

.Result

這是一個經典的UI線程死鎖。使用等待。在呼叫樹中使用它。

+0

謝謝,這個工程。我沒有掌握,我基本上不得不等待,直到我實際使用結果,並且不再向上傳遞。 – Lennart 2015-02-10 14:55:37

1

只是爲了澄清一點,'在調用樹中使用它'意味着您需要從UI線程調用它。類似這樣的:

private Task<string> DoWhileShowingDialogAsync() 
{ 
    return Task.Run(() => DoSomethingComplex()); 
} 

private string DoSomethingComplex() 
{ 
    // wait a noticeable time 
    for (int i = 0; i != 1000000000; ++i) 
    ; // do nothing, just wait 
} 

private async void GetResult() 
{ 
    pd.Show(); 
    string result = await DoWhileShowingDialogAsync(); 
    pd.Close(); 
}