当我遇到这个时,我在ASP.NET中做了一些编码:
protected async void someButtonClickHandler(...)
{
if(await blah)
doSomething();
else
doSomethingElse();
}
在询问this问题后,我更了解async
/ await
的工作原理。但是,让我感到震惊的是,按照上面显示的方式使用async
/ await
是否安全?
我的意思是在调用await blah
后调用者继续执行。这意味着它可能会在await blah
完成之前将响应呈现给客户端。这是正确的吗?如果是doSomething()
/ doSomethingElse()
会发生这种情况。他们会被处决吗?如果它们被执行了,用户是否会看到其变化的影响?
在我的情况下,这些方法会更改显示给用户的一些数据,但我也想知道在一般情况下会发生什么。
答案 0 :(得分:20)
是的,这是安全的,但不是真的推荐。 recommended way to do this is via RegisterAsyncTask
。MSDN article on async ASP.NET。但是,ASP.NET(Web窗体)将正确处理async void
事件处理程序。
处理程序await
时,响应不会呈现给客户端; await
仅产生ASP.NET运行时,而不是客户端。 ASP.NET运行时知道事件处理程序尚未完成,因此它知道不发送响应。当事件处理程序完成时,ASP.NET运行时通过在那时发送响应来响应。
我有an earlier MSDN article您可能会觉得有帮助。如果您对ASP.NET运行时如何意识到async
处理程序尚未完成感到好奇,我将在{{3}}中介绍它。
答案 1 :(得分:0)
我同意 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();
}