哪些ASP.NET生命周期事件可以异步?

时间:2013-01-02 00:31:51

标签: asp.net async-await

我编写了一个自定义ASP.NET控件,我刚刚将其更新为具有异步Load事件处理程序。现在我收到了这个错误:

  

此时无法启动异步操作。异步操作只能在异步处理程序或模块中启动,或者在页面生命周期中的某些事件中启动。如果在执行页面时发生此异常,请确保将页面标记为<%@ Page Async =“true”%>。

页面 已经有<%@ Page Async="true" %>标记。所以我认为控件不能有异步加载事件处理程序。

在哪里可以找到ASP.NET webforms生命周期中允许异步的事件的完整列表?

2 个答案:

答案 0 :(得分:28)

来自ASP.NET团队的Damian Edwards给出了这个答案:

  

Web表单中的异步void事件处理程序仅在某些情况下受支持   事件,正如你所发现的那样,但实际上只是为了简单化   任务。我们建议使用PageAsyncTask进行任何真实的异步工作   复杂性。

来自ASP.NET团队的Levi Broderick给出了这个答案:

  

Web应用程序中的异步事件本身就是一种奇怪的野兽。异步   void意味着火,忘记编程模型。这适用于   Windows UI应用程序自应用程序以来一直坚持到   操作系统会杀死它,因此每当异步回调运行时都会保证   是一个可以与之交互的UI线程。在Web应用程序中   由于请求是按照定义瞬态的,因此该模型会崩溃。如果   异步回调恰好在请求完成后运行,   无法保证回调所需的数据结构   与之互动仍处于良好状态。因此为什么火和忘记   (和async void)在Web应用程序中本质上是一个坏主意。

     

这   说,我们做疯狂的体操,试着做一些非常简单的事情   Page_Load工作,但支持这一点的代码非常复杂   除了基本情景之外,没有经过充分测试。所以,如果你   需要可靠性我坚持使用RegisterAsyncTask。

所以我认为我的问题的答案是:“这是错误的问题。”

正确的问题是“我的ASP.NET Web窗体应用程序中应该如何异步?”答案是将此代码段插入到您的aspx代码隐藏文件中:

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

同样的技巧在ASP.NET自定义控件中有效,只需使用this.Page.RegisterAsyncTask

答案 1 :(得分:1)

此页面解释异步页面中的生命周期事件处理与ASP.NET 2.0中的同步页面的处理不同(图2特别有用):

Wicked Code: Asynchronous Pages in ASP.NET 2.0

您也可以找到这个使用问题(它谈到相同的错误信息):

async keyword and choice of the TaskScheduler

相关问题