【发布时间】:2018-09-21 16:21:00
【问题描述】:
在使用async/await时,为了避免死锁,建议一直使用ConfigureAwait(false)直到最后一层。我知道使用 ConfigureAwait(false) 也会使当前的 HttpContext 为空。 Article
下面是示例代码,只是为了了解为什么ConfigureAwait(false) 没有在预期时将 HttpContext 设为 NULL,而在未预期时将其设为 NULL。
控制器
public class MyController : Controller
{
private readonly MyService _service = new MyService();
private readonly MyMapper _mapper = new MyMapper();
public async Task<ActionResult> DoSomething()
{
var data = await _service.GetData().ConfigureAwait(false);
// EXPECTED: Below, HttpContext should NOT NULL
// ACTUAL: HttpContext is NOT NULL as expected
if (HttpContext == null)
{
throw new ArgumentNullException("context");
}
var model = _mapper.Map(data);
return View(model);
}
}
将数据源异步调用到 GetData 的服务
public class MyService
{
public async Task<string> GetData()
{
// EXPECTED: HttpContext should be NULL here since we are calling
//this method from the Controller with ConfigureAwait(false)
// ACTUAL: HttpContext is NOT NULL, WHY?
if(HttpContext.Current == null)
{
throw new ArgumentNullException("context");
}
using (var client = new HttpClient())
{
var response = await client.GetAsync("http://url").ConfigureAwait(false);
response.EnsureSuccessStatusCode();
return await response.Content.ReadAsStringAsync().ConfigureAwait(false);
}
}
}
映射器类将数据映射到模型
public class MyMapper
{
public MyModel Map(string data)
{
// EXPECTED: HttpContext should NOT NULL here since async call is already done.
// ACTUAL: HttpContext is NULL here. WHY?
if (HttpContext.Current == null)
{
throw new ArgumentNullException("context");
};
return new MyModel()
{
Message = data
};
}
}
HttpContext 在MyService 中应为NULL,在MyMapper 中应为NOT NULL,但事实并非如此。请在 MyService 和 MyMapper 中查看我的内联 cmets
【问题讨论】:
标签: c# .net asp.net-mvc async-await