繁体   English   中英

在长时间运行的任务中显示自定义对话框窗口

[英]Displaying a custom dialog window during a long-running task

假设我有一个非常简单的带有IsIndeterminate=true ProgressBar:

<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只会无限死机,并且Task似乎永远不会返回。 问题不出在DoSomethingComplex()内,如果我同步运行它就可以毫无问题地完成。 我很确定这是因为我在使用await / async时误解了某些内容,有人可以指出我正确的方向吗?

.Result

这是经典的UI线程死锁。 使用等待。 在调用树中一直使用它。

只是为了澄清,“在调用树中一直使用它”意味着您需要从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();
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM