I was doing some coding in ASP.NET when I came across this:
protected async void someButtonClickHandler(...)
{
if(await blah)
doSomething();
else
doSomethingElse();
}
After asking this question I got a better understanding of how async
/await
works. But then it struck me is it safe to use async
/await
in the manner shown above?
I mean after calling await blah
the caller continues execution. Which means it might render the response back to client before await blah
completes. Is this right? And if this is the case what happens to doSomething()
/doSomethingElse()
. Will they ever be executed? If they're executed does the user see the effects of their changes?
In my case these methods change some data displayed to the user, but I'd also like to know what would happen in the general case.
Instead, you have to cast event handlers as async void if you want to run async code inside of an event handler method and to comply with the classic . NET event delegate signature. However, the real problem is that the event delegate is not called from a Task based context.
Async void methods can wreak havoc if the caller isn't expecting them to be async. When the return type is Task, the caller knows it's dealing with a future operation; when the return type is void, the caller might assume the method is complete by the time it returns.
When we don't want to return a result from our async method, we should always return a Task. To validate our asynchronous operations, we have to use the await keyword while calling that operation. When we convert our synchronous code to asynchronous, we have to use the async and await keywords all the way up the chain.
Best Practices for writing great async/await codeA try/catch block can be used to handle asynchronous errors in an async function. Alluding to the fact that an async function always return a Promise, one can opt to use a . catch() in place of a whole try/catch block.
Event handlers naturally return void, so async methods return void so that you can have an asynchronous event handler. However, some semantics of an async void method are subtly different than the semantics of an async Task or async Task<T> method.
All of these leads to improved scalability of our application. These two keywords – async and await – play a key role in asynchronous programming in ASP.NET Core. We use the async keyword in the method declaration and its purpose is to enable the await keyword within that method.
ASP.NET Web Forms is an older framework, but it also has adequate support for async and await. Again, the best resource for getting started is the tutorial on the ASP.NET Web site for async Web Forms (bit.ly/Ydho7W).
To summarize this first guideline, you should prefer async Task to async void. Async Task methods enable easier error-handling, composability and testability. The exception to this guideline is asynchronous event handlers, which must return void.
Yes it is safe, but not really recommended. The recommended way to do this is via RegisterAsyncTask
. However, ASP.NET (Web Forms) will correctly handle async void
event handlers.
The response is not rendered to the client when the handler await
s; the await
only yields to the ASP.NET runtime, not to the client. The ASP.NET runtime is aware that the event handler has not completed, so it knows not to send the response. When the event handler completes, the ASP.NET runtime responds by sending the response at that time.
I have an MSDN article on async ASP.NET that you may find helpful. If you're curious about how the ASP.NET runtime is aware that the async
handler has not completed, I cover that in an earlier MSDN article.
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