繁体   English   中英

async void事件处理程序 - 澄清?

[英]async void event handlers - clarification?

我试图理解为什么不好做的原因:( 注意,这里的上下文是asp.net,无论是否无法跟踪async void原因)

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

好吧,经过调查,我看到几个不同的原因:

  • 达米安·爱德华兹在这里说:

    Web表单中的异步void事件处理程序仅在某些事件上受支持 ,如您所见,但实际上仅用于简单的任务。 我们建议使用PageAsyncTask进行任何真正复杂的异步工作。

  • 列维在这里说:

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

    也就是说,我们做疯狂的体操试图制作非常简单的东西,如Page_Load工作,但支持这一点的代码非常复杂,并且没有经过基本场景之外的任何测试。 因此,如果您需要可靠性,我会坚持使用RegisterAsyncTask。

  • 这个网站说:

    我们知道我们的页面生命周期有一组事件以预定义的顺序触发,下一个事件只有在最后一个事件完成时才会触发。 因此,如果我们使用上述异步Page_Load方式,则在页面生命周期事件中,一旦它到达异步,当前线程被释放并且另一个线程被分配以异步完成任务,此事件将被触发, 但ASP.NET无法执行生命周期中的下一个事件,因为Page_Load尚未完成 底层同步上下文等待,直到异步活动完成。 然后,只会触发页面生命周期的下一个事件,这使得整个过程仅处于同步模式。

  • 这个网站说

    当返回类型为void时,调用者可能会认为该方法在返回时已完成 这个问题可能以许多意想不到的方式出现。 在接口(或基类)上提供void返回方法的异步实现(或覆盖)通常是错误的。 有些事件还假设他们的处理程序在返回时是完整的

我在这里看到非常不同 (非重叠)的原因。

题 :

什么是我们不应该写public async void Page_Load(object sender, EventArgs e)的荣耀/真正的原因public async void Page_Load(object sender, EventArgs e)


嗯,我也不知道为什么它是一个问题,因为4.5确实使用了其目的是支持UseTaskFriendlySynchronizationContext

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

您链接的文章使原因非常清楚。 不要使用它,因为除了最基本的场景之外它不可靠。 我们可以在异步void方法中引入同步上下文,只有很多异步跟踪技巧。 我们确实努力使这些基本方案工作,但我们的一般指导是避免使用它们,而是明确地注册异步工作。

我还没有验证这一点 ,但我认为只要页面有<%@ Page Async="true" ... %> ,就可以在ASP.NET 4.5 WebForms中使用async void Page_Load(...) <%@ Page Async="true" ... %>宣言。

我认为这是基于AspNetSynchronizationContext.OperationStarted实现,当在具有AspNetSynchronizationContext的线程上调用任何async void方法时调用AspNetSynchronizationContext 以下是相关评论:

 // 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.

显然, Async="true"页面不违反此要求,并且在完成所有挂起操作(包括async void操作)之前,不会完成HTTP请求处理。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM