2

In the below sample, when the async "Process" function is invoked synchronously, I can see the call to "await Task.Delay(1000)" causes the UI to hang.

I know I can avoid the hang by either calling "await Task.Delay(1000).ConfigureAwait(false)" or wrapping the "Process" invocation inside another task. I can understand the problem is with the synchornizationcontext, and I know await is doing something fancy with it i.e. if I replace the call "await Task.Delay(1000)" to "Task.Delay(1000).Wait()" the UI does not hang.

Can someone please explain the behavior (i did try looking at ildasm code but it didn't help). Thanks much.

public MainWindow()
{
    InitializeComponent();
    Loaded += OnLoaded;
}

public async void OnLoaded(object sender, RoutedEventArgs args)
{
    var task = Process();
    MessageBox.Show(task.Result);
}

public async Task<String> Process()
{
    await Task.Delay(1000);
    return "";
}


  • In short: task.Result means "hang the UI until the task is complete, then use the result". await task means "yield control to my caller; when the task is complete, schedule the continuation of the task to run at a convenient time in the future, and use the result then". - Eric Lippert

1 답변


3

First, methods are always invoked synchronously. When OnLoaded is invoked, it invokes the Process method.

The Process method invokes the Task.Delay method and gets back a reference to a Task<string> object which it awaits. This means that the code after the await is executed later and that the Process method returns at this point.

The OnLoaded method gets back a reference to a Task<string> object which it stores in the task variable. Then invokes the Result getter on the task. This blocks the current thread until the task completes.

One second later, the Process method tries continue. Because you started the task on the UI thread, the scheduler attempts to schedule the Process method on the UI thread. But the UI thread is blocked by the Result getter call, so the return ""; statement is never executed.


  • Sorry but it is not the case, the UI hangs and return "" is not even invoked (please set a breakpoint and see it for yourself). - Rohit Sharma
  • Thanks, not sure why it didn't click to me. :) - Rohit Sharma
  • +1. I describe this deadlock in more detail on my blog and MSDN article, and my blog post has links to more information including a couple of deadlock demos. - Stephen Cleary

Related

Latest