2013-01-02 33 views
27

我寫了一個自定義的ASP.NET控件,我只是更新它有一個異步Load事件處理程序。現在,我得到這個錯誤:哪些ASP.NET生命週期事件可以是異步的?

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" %>.

確實<%@ Page Async="true" %>標籤了。所以我認爲控件不能有異步加載事件處理程序。

我在哪裏可以找到ASP.NET webforms生命週期中允許爲異步的事件的綜合列表?

+2

本文可能會幫助您:http://msdn.microsoft.com/en-us/magazine/gg598924.aspx – Aristos

+1

謝謝。絕對是一個很好的閱讀,但它不回答我的問題。 –

+0

這也解釋了一點,並給出了比msdn更多的示例代碼,但仍然沒有回答你的問題:/ http://www.asp.net/web-forms/tutorials/aspnet-45/使用-asynchronous-asynchronous-methods-in-aspnet -45 – mirichan

回答

28

達米安從ASP.NET團隊愛德華茲給了這樣的回答:

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.

列維·布羅德里克從ASP.NET隊給了這樣的回答:

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.

所以我認爲,回答我的問題是:「這是一個錯誤的問題。」

正確的問題是「我的ASP.NET Web Forms應用程序中應該如何異步?」答案是插入你的aspx代碼隱藏文件裏面這個片段:

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

這同樣的伎倆作品裏面ASP.NET自定義控件,只需使用this.Page.RegisterAsyncTask代替。

1

本頁面介紹如何生命週期事件異步頁處理從ASP.NET 2.0的同步頁面的不同(圖2是特別有用):

Wicked Code: Asynchronous Pages in ASP.NET 2.0

您也可以找到這個問題的SO使用(它談到了同樣的錯誤消息):

async keyword and choice of the TaskScheduler

+0

謝謝,@Lokerim。特別是,有用的位是'Page.RegisterAsyncTask',它顯然允許我的ASP.NET自定義控件執行任何類型的異步操作,即使ASP.NET不允許我在自定義控件中使用「async void Page_Load」 。謝謝! –

相關問題