7

I'm trying to understand the reason why is it bad to do: (notice, context here is asp.net, regardless the plain reason that async void can't be tracked)

 public async void Page_Load(object sender, EventArgs e)
{
 ...
}

Well , after investigating a bit I saw few different reasons :

  • Damian Edwards Says here that:

    Async void event handlers in web forms are only supported on certain events, as you've found, but are really only intended for simplistic tasks. We recommend using PageAsyncTask for any async work of any real complexity.

  • Levi Says here that:

    Async events in web applications are inherently strange beasts. Async void is meant for a fire and forget programming model. This works in Windows UI applications since the application sticks around until the OS kills it, so whenever the async callback runs there is guaranteed to be a UI thread that it can interact with. In web applications, this model falls apart since requests are by definition transient. If the async callback happens to run after the request has finished, there is no guarantee that the data structures the callback needs to interact with are still in a good state. Thus why fire and forget (and async void) is inherently a bad idea in web applications.

    That said, we do crazy gymnastics to try to make very simple things like Page_Load work, but the code to support this is extremely complicated and not well-tested for anything beyond basic scenarios. So if you need reliability I’d stick with RegisterAsyncTask.

  • This site says:

    As we know our page life cycle has a set of events that gets fired in a predefined order and next event will be fired only when the last event completes. So if we use the above way of async Page_Load, this event will be fired during page life cycle event once it reaches to async, current thread gets free and a another thread got assigned to complete the task asynchronously, but the ASP.NET cannot execute the next event in life cycle because Page_Load has not been completed yet. And underlying synchronization context waits till the asynchronous activity completes. Then only the next event of page lifecycle will be fired which makes the whole process in synchronous mode only.

  • This site says

    when the return type is void, the caller might assume the method is complete by the time it returns. This problem can crop up in many unexpected ways. It’s usually wrong to provide an async implementation (or override) of a void-returning method on an interface (or base class). Some events also assume that their handlers are complete when they return.

I see here very different (non-overlapping) reasons.

Question :

What is the glory/true reason for which we shouldn't write public async void Page_Load(object sender, EventArgs e) ?


nb, I also don't know why it is a problem since 4.5 does use the UseTaskFriendlySynchronizationContext which its aim is to support:

protected async void Page_Load(object sender, EventArgs e){...}

Community
  • 1
  • 1
Royi Namir
  • 144,742
  • 138
  • 468
  • 792
  • Notice how all of the ASP related links say that it's okay, and all of the non-ASP related links say that you should be very careful about how you use `async void`. That should tell you something, that ASP is special. And if you read through some of your own links, they even explain *why* ASP is special, and how it went about allowing `async void` methods to work as you would want them to; of course, that's only for the simple cases; it also explains when it won't work, and what to do then. – Servy May 01 '14 at 14:43
  • @Servy Levi and Damian are in the asp.net development....so i found it hard not to believe them....but on the other hand....the other reasons seems legit also....so...:-) – Royi Namir May 01 '14 at 16:02

2 Answers2

5

The articles you link to make the reasons pretty clear. Don't use it because it isn't reliable beyond the most basic of scenarios. There is only so much async tracking trickery we can pull in the synchronization context on async void methods. We did work to make those basic scenarios work, but our general guidance is to avoid using them and instead explicitly register async work.

Damian Edwards
  • 7,289
  • 1
  • 25
  • 19
  • Hello Damian, in an effort to "avoid async void" I used the `RegisterAsyncTask` during the Page_Load eventhandler, but I was unable to get any data to bind to the Telerik RadGrid. The methods are all called and return data, but the data bind fails. Could you help me understand what might be going wrong? – Pramod Mangalore Mar 15 '15 at 22:10
2

I haven't verified this, but I think it's OK to use async void Page_Load(...) in ASP.NET 4.5 WebForms, for as long as the page has <%@ Page Async="true" ... %> declaration.

I think so based on the implementation of AspNetSynchronizationContext.OperationStarted, which is called when any async void method is invoked on a thread with AspNetSynchronizationContext. Here's a relevant comment:

 // If the caller tries to kick off an asynchronous operation while we are not
 // processing an async module, handler, or Page, we should prohibit the operation.

Apparently, pages with Async="true" do not violate this requirement, and the HTTP request processing isn't going to be completed until all pending operations have completed, including async void ones.

noseratio
  • 59,932
  • 34
  • 208
  • 486