2015-02-10 128 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(); 
}