Roy*_*mir 7 c# asp.net async-await c#-5.0 .net-4.5
我试图理解为什么不好做的原因:( 注意,这里的上下文是asp.net,不管async void无法跟踪的原因)
public async void Page_Load(object sender, EventArgs e)
{
...
}
Run Code Online (Sandbox Code Playgroud)
好吧,经过调查,我看到几个不同的原因:
达米安·爱德华兹在这里 说:
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)?
嗯,我也不知道为什么它是一个问题,因为4.5确实使用了其 目的是支持的UseTaskFriendlySynchronizationContext:
protected async void Page_Load(object sender, EventArgs e){...}
您链接的文章使原因非常清楚.不要使用它,因为除了最基本的场景之外它不可靠.我们可以在异步void方法中引入同步上下文,只有很多异步跟踪技巧.我们确实努力使这些基本方案工作,但我们的一般指导是避免使用它们,而是明确地注册异步工作.
| 归档时间: |
|
| 查看次数: |
903 次 |
| 最近记录: |