I read alot about async/await
, but I still have some lack in understanding the following situation.
My question is, should I implement my "wrapper" methods as in DoSomething()
or like in DoSomethingAsync()
.
So what's better (and why): Do I use await
in wrapper methods or return the Task directly?
public static async void Main()
{
await DoSomething();
await DoSomethingAsync();
}
private static Task DoSomething()
{
return MyLibrary.DoSomethingAsync();
}
private static async Task DoSomethingAsync()
{
await MyLibrary.DoSomethingAsync().ConfigureAwait(false);
}
public class MyLibrary
{
public static async Task DoSomethingAsync()
{
// Here is some I/O
}
}
If you forget to use await while calling an async function, the function starts executing. This means that await is not required for executing the function. The async function will return a promise, which you can use later.
The await operator doesn't block the thread that evaluates the async method. When the await operator suspends the enclosing async method, the control returns to the caller of the method.
You can use the following simple workaround in the scenario where you want to call an async method from a sync method: Before the call, clear the SynchronizationContext. Do the call, there will be no more deadlock here, wait for it to finish. Restore the SynchronizationContext.
Async/Await are still relatively new, but there are some good practices to help clarify an API. The basics are this:
async
means it is expecting to await
later onasync
implicitly creates a Task
for you.await
is like a bookmark. The application resumes where the await keyword was used.await
anything that is not IAwaitable
(most commonly a Task
) (citation)In an application where there are both asynchronous calls and synchronous calls, we've adopted a naming convention:
async
calls return Task
or Task<T>
and append the word Async
to the end of the name.Often, there can be two methods which do the same thing, but one is synchronous and the other not. You can either implement it two different ways, or you can wrap one with the other. It really depends on your needs and what is going to give you the more responsive application.
In the example above, the proper way to handle async and normal method calls would be for MyLibrary
to expose two methods. The example would be like this:
public static class MyLibrary
{
public static void DoSomething()
{
// do some work
}
public static async Task DoSomethingAsync()
{
// do similar work but use async API,
// can also simply call DoSomething().
}
}
// In another part of code would be called like this:
public static async Task BiggerMethod()
{
MyLibrary.DoSomething();
await MyLibrary.DoSomethingAsync();
}
What you want to avoid is wrapping an async
method with a regular method. As soon as you work with the Task
directly, you lose all benefits of async
and await
and you introduce places where your code can deadlock.
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