c# - 显示对话框后启动时任务卡住 UI

标签 c# wpf responsive-design task-parallel-library synchronizationcontext

假设我们想要显示一个对话框,当 task1 中出现异常时,我们从该对话框调用一个方法,该方法启动一个新的 task2。问题是所有者窗口在 task2 期间卡住。

请看一下简单的代码( Task Parallel Library 使用):

private void button1_Click(object sender, RoutedEventArgs e)
{   
    var scheduler = TaskScheduler.FromCurrentSynchronizationContext();
    Task.Factory.StartNew
      (() => SomeHardMethod(1)).ContinueWith(TaskContinuation, scheduler);
}
private void TaskContinuation(Task parentTask)
{   
    if (parentTask.IsFaulted)
    {
        // If we get an exception - show a dialog that starts a new task
        var dlg = new WindowDialog();  
        var scheduler = TaskScheduler.FromCurrentSynchronizationContext();
        if (dlg.Show())
        {   
          //Here we start a new task
           Task.Factory.StartNew
             (() => SomeHardMethod(2)).ContinueWith(TaskContinuation, scheduler);
        }
        var ex = parentTask.Exception;
    }
}
private void SomeHardMethod(int mode)
{   
    if (mode == 1)
    {    
         throw new ArgumentException("mode");
    }
    else
    {   //Any long operation...
        Thread.Sleep(3000);
    }    
}

对我来说,奇怪的是,当我第一次在 button1_Click 方法中启动任务时,它不在 UI 中执行,但是当我第二次启动新任务时,它在 UI 线程中执行,所以这就是为什么所有者窗口卡住。

有人能澄清为什么这部分代码实际上不在后台启动任务吗?

if (dlg.Show())
{
    //Here we start a new task
    Task.Factory.StartNew
      (() => SomeHardMethod(2)).ContinueWith(TaskContinuation, scheduler);
}

最佳答案

当您使用 Task.Factory.StartNew() 启动 Task 时,current scheduler用来。这意味着,如果您以这种方式从在 UI 线程上执行的 Task 启动一个 Task,它也将在 UI 线程上执行。但是,如果您从 UI 线程但在 Task 之外(例如在事件处理程序中)启动 Task,则不会发生同样的情况。

为了确保Task在后台线程上执行,您需要明确指定您要使用TaskScheduler.Default .

关于c# - 显示对话框后启动时任务卡住 UI,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16497158/

相关文章:

c# - 试图在编译时分配一个大数字

c# - 列表中的枚举值

wpf - 为什么 Process.WaitForInputIdle() 不起作用?

responsive-design - 如何使用Dart获得以英寸为单位的屏幕实际尺寸?

twitter-bootstrap - 水平滚动导航栏 Bootstrap

c# - 如何防止 WPF DataGrid 在项目更新时取消选择 SelectedItem?

c# - C# 默认位置中的配置文件?

c# - 根据您放入另一个 WPF 的信息将值/打开文件放入 WPF

c# - 如果您将姓名留空,如何保存 ID?

css - 带有 flexbox 的响应式列