在 ASP.NET 事件处理程序中使用 async/await 是不是安全?

Posted

技术标签:

【中文标题】在 ASP.NET 事件处理程序中使用 async/await 是不是安全?【英文标题】:Is it safe to use async/await in ASP.NET event handlers?在 ASP.NET 事件处理程序中使用 async/await 是否安全? 【发布时间】:2015-02-01 15:49:15 【问题描述】:

当我遇到这个时,我正在用 ASP.NET 编写代码:

protected async void someButtonClickHandler(...)

    if(await blah)
        doSomething();
    else
        doSomethingElse();

在问了this 的问题后,我对async/await 的工作原理有了更好的了解。但后来让我印象深刻的是,以上述方式使用async/await 是否安全? 我的意思是在调用await blah 之后,调用者继续执行。这意味着它可能会在await blah 完成之前将响应呈现给客户端。这是正确的吗?如果是这种情况,doSomething()/doSomethingElse() 会发生什么。他们会被处决吗?如果它们被执行,用户是否会看到其更改的效果? 就我而言,这些方法会更改向用户显示的一些数据,但我也想知道在一般情况下会发生什么。

【问题讨论】:

这适用于网络表单吗? 【参考方案1】:

是的,它是安全的,但不是很推荐。 recommended way to do this is via RegisterAsyncTask。但是,ASP.NET(Web 窗体)将正确处理 async void 事件处理程序。

当处理程序awaits 时,响应不会呈现给客户端; await 只屈服于 ASP.NET 运行时,而不是客户端。 ASP.NET 运行时知道事件处理程序尚未完成,因此它知道不发送响应。当事件处理程序完成时,ASP.NET 运行时通过发送响应来响应。

我有一个MSDN article on async ASP.NET,您可能会觉得有帮助。如果您对 ASP.NET 运行时如何知道 async 处理程序尚未完成感到好奇,我将在 an earlier MSDN article 中进行介绍。

【讨论】:

您的第一个链接目前已损坏 @Fredou:链接正确;这是 ASP.NET 站点的问题。只需点击刷新,直到内容出现。【参考方案2】:

我同意 Stephens 的回答(简而言之,ASP.NET SynchronisationContext 会监视正在运行的任务数量),但因为它是(最好避免的)async void,您可能想要记录任何否则会被忽视的异常:

protected async void someButtonClickHandler(...)

    try
        await someButtonClickHandlerInner(...)
    
    catch (AggregateException ex)
    
        logger.log(ex.flatten());
    
    catch(Exception e)
        logger.log(e);  
    


private async Task someButtonClickHandlerInner(...)
    if(await blah)
        doSomething();
    else
        doSomethingElse();

【讨论】:

以上是关于在 ASP.NET 事件处理程序中使用 async/await 是不是安全?的主要内容,如果未能解决你的问题,请参考以下文章

ASP.NET:如何在订阅的事件处理程序中更新前端

我的 Asp.net 核心应用程序事件处理程序不起作用

ASP.NET 事件处理

关于asp.net中页面事件加载的先后顺序

通过 ASP.NET Web API 有效地使用 async/await

ASP.NET MVC中注册Global.asax的Application_Error事件处理全局异常