2

I have a console application with the following code

static void Main(string[] args) {
    Method();
    Console.ReadKey();
}

private static void Method() {
    Task t = DoSomething();
    t.Wait();
    Console.WriteLine("Finished");
}

private static async Task DoSomething() {
    await Task.Run(() =>
        Thread.Sleep(1000));
}

Everything works exactly as I expect it to and the console displays "Finished" one second after running the program. When I move the same code into a windows application then I find that the program just stops

private void button1_Click(object sender, EventArgs e) {
    Task t = DoSomething();
    t.Wait();
    MessageBox.Show("Finished");
}

private static async Task DoSomething() {
    await Task.Run(() =>
        Thread.Sleep(1000));
}

The debugger shows the current line of execution is t.Wait(), even after the Task in the DoSomething method has been run.

Is there something different that I need to do in a windows application that I don't need to do in a console application? Or am I fundamentally misunderstanding something?

Jonny
  • 2,509
  • 23
  • 42

1 Answers1

5

That's something that happens quite often. You're causing a deadlock.

To put it simply, frameworks like WinForms and WPF "enforce" a thread synchronization context, which means that whenever you launch a new task, the rest of your code will continue on the same thread as it started. This is done to ensure that, for example, code that started on the UI thread will continue running on the same thread after the task returns.

Because you're blocking on the task (with the Wait method), and the task is trying to return a value to that blocking thread, both threads go into a deadlock state.

This behaviour doesn't happen in a console application because no thread synchronization context is enforced, the continuation of a task can run on a completely different third thread.

Stephen Cleary explains this very well here: http://blog.stephencleary.com/2012/07/dont-block-on-async-code.html

dcastro
  • 66,540
  • 21
  • 145
  • 155