Which ASP.NET lifecycle events can be async?

I’ve written a custom ASP.NET control and I just updated it to have an async Load event handler. Now I’m getting this error:

An asynchronous operation cannot be started at this time. Asynchronous operations may only be started within an asynchronous handler or module or during certain events in the Page lifecycle. If this exception occurred while executing a Page, ensure that the Page is marked <%@ Page Async=”true” %>.

The page does have the <%@ Page Async="true" %> tag already. So I take it that controls can’t have async load event handlers.

Where can I find a comprehensive list of events in the ASP.NET webforms lifecycle that are allowed to be async?

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

Damian Edwards from the ASP.NET team gave this answer:

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 Broderick from the ASP.NET team gave this answer:

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.

So I think the answer to my question is: “That’s the wrong question.”

The right question would be “How should I be async in my ASP.NET Web Forms application?” And the answer is to insert this snippet inside your aspx code-behind file:

this.RegisterAsyncTask(new PageAsyncTask(async cancellationToken => {
    var result = await SomeOperationAsync(cancellationToken);
    // do something with result.
}));

This same trick works inside ASP.NET custom controls, just use this.Page.RegisterAsyncTask instead.

Method 2

This page explains how life cycle event handling in asynchronous pages differs from those of synchronous pages in ASP.NET 2.0 (Figure 2 is especially helpful):

Wicked Code: Asynchronous Pages in ASP.NET 2.0

You may also find this SO question of use (it talks about the same error message):

async keyword and choice of the TaskScheduler


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x