Question

Suppose we want to show a dialog, when getting an exception in the task1 and from that dialog we call a method, which starts a new task2. The problem is that the owner window freezes during task2.

Please, take a look at the simple code (Task Parallel Library uses):

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

To me, its strange that, when I firstly start the task in button1_Click method it performs not in UI, but when I secondly start a new task it performs in UI thread, so that's why the owner window freezes.

Could anyone clarify why does this part of code actually start the task not in background?

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

Solution

When you start a Task using Task.Factory.StartNew(), the current scheduler is used. What this means is that if you start a Task this way from a Task that executes on the UI thread, it will execute on the UI thread too. But the same won't happen if you start a Task from the UI thread, but outside of a Task (like in your event handler).

To make sure the Task is executed on a background thread, you need to explicitly specify you want to use TaskScheduler.Default.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top