异步无效,ASP.Net和未完成 *** 作的数量

异步无效,ASP.Net和未完成 *** 作的数量,第1张

异步无效,ASP.Net和未完成 *** 作的数量

Microsoft做出了避免在引入

async
ASP.NET
时尽可能避免向后兼容性问题的决定。他们希望将其引入所有“一个ASP.NET”中-因此
async
支持WinForms,MVC,WebAPI,SignalR等。

从历史上看,ASP.NET从.NET
2.0开始就通过基于事件的异步模式(EAP)支持干净的异步 *** 作,其中异步组件将

SynchronizationContext
其开始和完成通知给。.NET
4.5对该支持进行了第一个相当大的更改,更新了核心ASP.NET异步类型以更好地启用基于任务的异步模式(TAP,即
async
)。

同时,每个不同的框架(WebForm,MVC等)都开发了自己的与该内核进行交互的方式,将 向后兼容性
作为优先事项。为了帮助开发人员,

SynchronizationContext
除了您看到的异常之外,还增强了核心ASP.NET 。它将捕获许多使用错误。

在WebForms世界中,他们有,

RegisterAsyncTask
但是很多人只使用
async void
事件处理程序。因此,ASP.NET
SynchronizationContext
async void
在页面生命周期的适当时间允许访问,如果在不适当的时间使用它,则会引发该异常。

在MVC / WebAPI / SignalR世界中,框架被结构化为服务。因此,他们能够以

asyncTask
非常自然的方式采用,并且该框架只需要处理返回的内容
Task
-一个非常干净的抽象。附带说明,您不再需要
AsyncController
了。MVC知道它是异步的,因为它返回
Task

但是,如果您尝试返回a

Task
使用
asyncvoid
,则不支持。而且没有什么理由支持它。仅支持不应该这样做的用户将是非常复杂的。请记住,它
asyncvoid
SynchronizationContext
直接绕过MVC框架直接通知核心ASP.NET
。MVC框架了解如何等待您,
Task
但它甚至不了解
async void
,因此它将完成返回到ASP.NET核心,该核心看到它 实际上 尚未完成。

在两种情况下,这可能会导致问题:

  1. 您正在尝试使用某些库或使用的库
    async void
    。抱歉,但是明显的事实是该库已损坏,必须修复。
  2. 您正在将EAP组件包装到中,
    Task
    并正确使用
    await
    。这可能会导致问题,因为EAP组件
    SynchronizationContext
    直接与之交互。在这种情况下,最好的解决方案是修改类型,使其自然支持TAP或将其替换为TAP类型(例如
    HttpClient
    代替
    WebClient
    )。如果失败,则可以使用TAP上的TAP而不是EAP上的TAP。如果这两种方法都不可行,则可以
    Task.Run
    在TAP-EAP-EAP包装器周围使用。

关于“忘了忘了”:

我个人从不使用此短语作为

async void
方法。一方面,错误处理的语义最肯定不适合短语“即发即弃”。我开玩笑地将
asyncvoid
方法称为“火灾和崩溃”。真正的
async
“解雇”方法将是
async Task
您忽略返回
Task
而不是等待返回的方法。

就是说,在ASP.NET中,您几乎永远都不想从请求中早返回(这就是“一劳永逸”的含义)。这个答案已经太长了,但是我确实在博客上描述了这些问题,并在确实需要的情况下提供了一些支持ASP.NET“即弃即用”的代码。



欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/4976388.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-11-14
下一篇 2022-11-14

发表评论

登录后才能评论

评论列表(0条)

保存