我有以下测试WebAPI代码,我不在生产中使用WebAPI,但是因为我参与了这个问题的讨论,所以写了这个代码:WebAPI异步问题
无论如何,这是有问题的WebAPI方法:
public async Task<string> Get(int id)
{
var x = HttpContext.Current;
if (x == null)
{
// not thrown
throw new ArgumentException("HttpContext.Current is null");
}
await Task.Run(() => { Task.Delay(500); id = 3; });
x = HttpContext.Current;
if (x == null)
{
// thrown
throw new ArgumentException("HttpContext.Current is null");
}
return "value";
}
我曾经认为第二个异常是可以预料的,因为当await
完成时,它很可能会在另一个线程上,而HttpContext.Current
作为线程静态变量将不再解析为适当的值。现在,基于同步上下文,它实际上可能被强制返回到相同的线程,但在我的测试中没有进行任何花哨的操作。这只是一个简单、天真的使用await
。
在另一个问题的评论中,有人告诉我HttpContext.Current
应该在await
之后解析。甚至在这个问题的另一个评论中也有相同的说法。那么什么是真的呢?它应该解析吗?我认为不应该,但我希望能得到权威的答案,因为async
和await
还不够成熟,我找不到明确的信息。
TL;DR: 在await
之后,HttpContext.Current
是否可能为null
?
AspNetSynchronizationContext
来处理HttpContext
,而不是await
。此外,await
的继续回调可能(并且很可能)在Web API执行模型的不同线程上发生。 - noseratio - open to work.ConfigureAwait(false)
时,这个库就会出现问题。由于业务层不具备Web感知能力,因此没有请求或控制器明确地传递。例如,对于一个日志记录模块,当业务逻辑编写通用的TraceInformation
时,它可以注入请求详细信息,这非常有用。 - Joep Beusenberg