8

What is the behavior of calling an async method without the await and in a non-async method? I'm asking because I see Visual Studio not displaying any warning on the call to the async method as if it were a perfectly normal thing to do. Does the async method behave as if it were synchronous in such case?

Igor
  • 60,821
  • 10
  • 100
  • 175
whatever
  • 2,492
  • 6
  • 30
  • 42
  • Possible duplicate of [How would I run an async Task method synchronously?](https://stackoverflow.com/questions/5095183/how-would-i-run-an-async-taskt-method-synchronously), [Calling async method synchronously](https://stackoverflow.com/questions/22628087), [Calling async methods from non-async code](https://stackoverflow.com/questions/40324300). – Igor Aug 29 '17 at 15:58

2 Answers2

6

It's not uncommon for async methods to be called in this fire-and-forget fashion (and yes, the usual advice regarding not using/being extra careful with async void also fully applies in this case).

Calling an async method from a method which does not have the async modifier does not result in the async method executing synchronously.

Instead, the async method will execute up to the first await on an awaitable having IsCompleted == false (i.e. first awaited instance of Task which does not complete synchronously). At that point the calling (outer) method will resume execution, and the rest of the async method will be scheduled to run at a later point.

Kirill Shlenskiy
  • 9,367
  • 27
  • 39
6

The fact that a method has async as a modifier is an implementation detail of the method. It just means you can write asynchronous code more easily. It doesn't change how the method is called at all.

Typically an async method returns Task or Task<T>. It can return void, but that's usually only used for event handlers, as otherwise the caller can't tell when the method has completed. In C# 7 it can also return a custom task type.

Now how the caller uses that return value is up to them. Suppose a method returns Task<int> - a synchronous method might call that method then ignore the returned task completely ("fire and forget"), or attach a continuation with ContinueWith, or pass it to an async method that will await it. None of that changes how the async method itself behaves.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194