简体   繁体   English

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

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

Let's say I have a very simple ProgressBar with IsIndeterminate=true : 假设我有一个非常简单的带有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>

I want to show this dialog during a Task that may take a while. 我想在可能需要一段时间的任务中显示此对话框。 I don't care about progress (I can't determine it), I just want to inform the user that I do something that may take some seconds. 我不在乎进度(我无法确定进度),我只是想通知用户我做了一些可能要花几秒钟的时间。

 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;
}

However the UI just freezes infinitely and the Task seems to never return. 但是,UI只会无限死机,并且Task似乎永远不会返回。 The problem doesn't lie within DoSomethingComplex(), it completes without issues if I run it synchronously. 问题不出在DoSomethingComplex()内,如果我同步运行它就可以毫无问题地完成。 I'm pretty sure it's because I misunderstood something with await/async, can someone point me in the right direction? 我很确定这是因为我在使用await / async时误解了某些内容,有人可以指出我正确的方向吗?

.Result

That's a classic UI thread deadlock. 这是经典的UI线程死锁。 Use await. 使用等待。 Use it all the way up the call tree. 在调用树中一直使用它。

Just for some clarification, 'use it all the way up the call tree' means you need to call it from the UI thread. 只是为了澄清,“在调用树中一直使用它”意味着您需要从UI线程调用它。 Something like this: 像这样:

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.

相关问题 Rx如何并行化长时间运行的任务? - Rx How to parallelize long-running task? 长期运行的后台任务中的Internet访问 - Internet access in a long-running background task 可以使用任务并行库一起运行长时间运行的方法和“正在工作...”对话框以允许将长时间任务写入 BindingList 吗? - Can a long-running method and a “Working…” dialog be run together using the Task Parallel Library to allow long task to write to a BindingList? 使用对话框执行长任务 - Long running task with dialog 在Windows服务中运行长时间运行的任务 - Running a long-running Task within a Windows Service 在长时间运行过程中禁用鼠标点击? - Disable mouse clicks during long-running process? WinForm 应用程序 UI 在长时间运行期间挂起 - WinForm Application UI Hangs during Long-Running Operation 长期运行任务与线程 - 性能 - Long-running task vs. threads — performance 在Winforms中显示模式加载窗口以长时间运行 - Show modal loading window in Winforms for long-running process 在后台运行一个长时间运行的并行任务,同时允许小的异步任务更新前台 - Running a long-running parallel task in the background, while allowing small async tasks to update the foreground
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM