【问题标题】:Task frezees UI when starts after showing a dialog任务在显示对话框后启动时冻结 UI
【发布时间】:2013-05-11 12:37:21
【问题描述】:

假设我们想要显示一个对话框,当在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);
}

【问题讨论】:

  • WindowDialog 到底是什么,Show() 有什么作用?
  • 它实际上并没有发生。在我的情况下,它只显示一个窗口,并且有一个按钮,只需关闭它(DialogResult = true)
  • 它应该 ShowDialog() 窗口。细节很重要。

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


【解决方案1】:

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

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

【讨论】:

  • 感谢您的澄清!这有助于理解机制现在我将尝试使用您的提示解决问题。
猜你喜欢
  • 1970-01-01
  • 2022-11-24
  • 1970-01-01
  • 2015-06-20
  • 2011-04-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-22
相关资源
最近更新 更多