在使用async/await
时,为避免死锁,建议使用ConfigureAwait(false)
一直到最后一层。我知道使用 ConfigureAwait(false)
也会使当前的 HttpContext 为空。 Article
下面的示例代码只是为了理解为什么 ConfigureAwait(false)
没有在预期时将 HttpContext 设为 NULL,而在不需要时将其设为 NULL。
Controller
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);
}
}
对数据源进行异步调用以获取数据的服务
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
最佳答案
你把它倒过来了。 HttpContext.Current
将在上下文切换之后为 null,而不是之前。
所以:
// ACTUAL: HttpContext is NOT NULL, WHY?
if(HttpContext.Current == null)
{
throw new ArgumentNullException("context");
}
不,预期不是null
,因为到目前为止还没有任何await
(父await
不适用)。
// EXPECTED: HttpContext should NOT NULL here since async call is already done.
// ACTUAL: HttpContext is NULL here. WHY?
if (HttpContext.Current == null)
切换发生在这一行之后
var response = await client.GetAsync("http://url").ConfigureAwait(false);
所以它应该是null
。
关于c# - ConfigureAwait(false) 没有按预期使 HttpContext NULL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49780873/