Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is AsyncContext needed when using async/await with a console application?

I'm calling an async method within my console application. I don't want the app to quit shortly after it starts, i.e. before the awaitable tasks complete. It seems like I can do this:

internal static void Main(string[] args)
{
    try
    {
        Task.WaitAll(DoThisAsync());
    }
    catch (Exception ex)
    {
        Console.Error.WriteLine(ex);
        throw;
    }
}

internal static async Task DoThisAsync()
{
    //...
}

But according to Stephen Cleary's article it seems like I can't do that and should instead create some kind of context for the async to return to when it's done (e.g. AsyncContext).

The code above works though, and it returns on the main thread after Task.WaitAll(DoThisAsync());, so why do I need to use a custom context?

like image 590
rory.ap Avatar asked Mar 03 '15 19:03

rory.ap


People also ask

What is Asynccontext C#?

Simplifies the setup of a SynchronizationContext for the use of async calls in the current thread.

What is the purpose of async await keywords?

The async keyword turns a method into an async method, which allows you to use the await keyword in its body. When the await keyword is applied, it suspends the calling method and yields control back to its caller until the awaited task is complete. await can only be used inside an async method.

Does async await use thread pool?

The async and await keywords don't cause additional threads to be created. Async methods don't require multithreading because an async method doesn't run on its own thread. The method runs on the current synchronization context and uses time on the thread only when the method is active.

What is one benefit of using async await?

A significant benefit of the async/await pattern in languages that support it is that asynchronous, non-blocking code can be written, with minimal overhead, and looking almost like traditional synchronous, blocking code.


1 Answers

It's not required; it's just my preference.

You can synchronously block on a task within Main (using Wait/Result/WaitAll). The semantics are slightly different; in particular, if the async code fails, then Wait/Result/WaitAll will wrap the exception in an AggregateException, while AsyncContext does not.

Also, AsyncContext treats the main thread specially; instead of sending continuations to the thread pool, it will send them back to that main thread (by default; you can always use ConfigureAwait(false) to avoid this). I find this useful if I'm writing a "proof of concept" console app, because AsyncContext behaves very similarly to the UI contexts.

But at the end of the day, it's just a matter of preference.

like image 82
Stephen Cleary Avatar answered Oct 10 '22 02:10

Stephen Cleary