3

I think I have successfully confused myself for the day.

public void DoSomething1()
{
    Task.Delay(1000);
}

public async void DoSomething2()
{
    await Task.Delay(1000);
}

What is the difference between these two functions in terms of what happens within them when they are called? What is the purpose of using an async method that does not return a Task?

KDecker
  • 6,928
  • 8
  • 40
  • 81
  • 2
    Both of these methods successfully do nothing, equally well. These two methods are identical to `public void DoSomething3(){}` (outside of the fact that those two will consume a handful of CPU cycles in accomplishing nothing). – Servy Jan 26 '16 at 20:51
  • Does the `Task.Delay` not run at all in either? – KDecker Jan 26 '16 at 20:53
  • 1
    It runs. It accomplishes nothing. Both methods are saying, "Do nothing one second from now" which is identical to just saying, "do nothing". – Servy Jan 26 '16 at 20:53
  • If I were to call either of these functions, would there be any difference in calling one or the other? – KDecker Jan 26 '16 at 20:57
  • How does my first comment not answer that question? – Servy Jan 26 '16 at 21:00

1 Answers1

6

What is the difference between these two functions in terms of what happens within them when they are called?

DoSomething1 is a synchronous method. As such:

  • It starts an asynchronous delay and then ignores it.
  • Any exceptions from the asynchronous delay are silently ignored.
  • Any exceptions from DoSomething are raised directly to the caller.

DoSomething2 is an asynchronous void method. As such:

  • It starts an asynchronous delay and then observes it.
  • Any exceptions from the asynchronous delay are re-raised on the SynchronizationContext that was current at the time DoSomething2 started executing. This generally results in program termination.
  • Any exceptions from DoSomething2 are also raised on that SynchronizationContext, with the same result.

What is the purpose of using an async method that does not return a Task?

async void is not a natural thing. For example, the equivalent simply does not exist in F#. async void was added to C#/VB to enable event handlers to become asynchronous without changing the entire event handling or delegation system.

In short, you should avoid async void, and only use them for event handlers (or logical equivalents to event handlers, like ICommand.Execute in MVVM).

Stephen Cleary
  • 437,863
  • 77
  • 675
  • 810