【问题标题】:Which ASP.NET lifecycle events can be async?哪些 ASP.NET 生命周期事件可以是异步的?
【发布时间】:2012-12-16 10:34:30
【问题描述】:

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

此时无法启动异步操作。异步操作只能在异步处理程序或模块内或在页面生命周期中的某些事件期间启动。如果在执行页面时发生此异常,请确保将页面标记为 。

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

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

【问题讨论】:

  • 这篇文章对你有帮助:msdn.microsoft.com/en-us/magazine/gg598924.aspx
  • 谢谢。绝对是一本好书,虽然它没有回答我的问题。
  • 这也解释了一点,并提供了比 msdn 更多的示例代码,但仍然没有回答您的问题:/ asp.net/web-forms/tutorials/aspnet-45/…
  • 您是如何将您的 Load 事件处理程序更新为异步的?你能提供那个事件处理程序的代码吗?
  • 私有异步 void Page_Load(...)

标签: asp.net async-await


【解决方案1】:

本页解释了异步页面中的生命周期事件处理与 ASP.NET 2.0 中同步页面的处理方式有何不同(图 2 尤其有用):

Wicked Code: Asynchronous Pages in ASP.NET 2.0

您可能还会发现这个 SO 使用问题(它谈到了相同的错误消息):

async keyword and choice of the TaskScheduler

【讨论】:

  • 谢谢,@Lokerim。特别是,有用的位是Page.RegisterAsyncTask,它显然允许我的 ASP.NET 自定义控件执行任何类型的异步操作,即使 ASP.NET 不允许我在自定义控件中使用“async void Page_Load”。谢谢!
【解决方案2】:

ASP.NET 团队的 Damian Edwards 给出了这样的答案:

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

ASP.NET 团队的 Levi Broderick 给出了这样的答案:

Web 应用程序中的异步事件本质上是奇怪的野兽。异步 void 是一种“一劳永逸”的编程模型。这适用于 Windows UI 应用程序,因为应用程序一直存在,直到 操作系统会杀死它,因此只要异步回调运行,就可以保证 成为可以与之交互的 UI 线程。在网络应用程序中, 这个模型分崩离析,因为根据定义,请求是瞬态的。如果 异步回调恰好在请求完成后运行, 不能保证回调需要的数据结构 互动还处于良好的状态。因此,为什么火而忘记 (和 async void)在 Web 应用程序中本质上是一个坏主意。

那个 说,我们做疯狂的体操,试图做一些非常简单的事情,比如 Page_Load 工作,但支持它的代码非常复杂 并且没有针对基本场景之外的任何内容进行良好测试。所以如果你 需要可靠性,我会坚持使用 RegisterAsyncTask。

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

正确的问题是“我应该如何在我的 ASP.NET Web 窗体应用程序中实现异步?”答案是在你的 aspx 代码隐藏文件中插入这个 sn-p:

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

同样的技巧也适用于 ASP.NET 自定义控件,只需使用 this.Page.RegisterAsyncTask 代替。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-09
    • 1970-01-01
    • 2020-05-07
    • 1970-01-01
    • 2020-05-10
    相关资源
    最近更新 更多