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?
Simplifies the setup of a SynchronizationContext for the use of async calls in the current thread.
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.
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With