我有一个关于Web应用程序,使异步HTTP POST一个非常奇怪的情况...期待已久的异步任务失去HttpContext.Current
我们在TFS两个分支。我将代码从一个分支合并到另一个分支,然后发现由于System.NullReferenceException,新分支中的一些集成测试失败。我花时间确保两个分支中的代码是相同的,并且所有引用的DLL也是相同的。一切似乎都一样。
所以,我决定调试测试。
我们的测试所做的是创建一个模拟IHttpClient对象。我们以这样的方式存储Mock对象,clientMock.PostAsyncWithResponseMessage(x,y)返回一个新的HttpResponseMessage()对象(我们在其中设置了各种属性)。
所以,代码如下:
using (var response = await client.PostAsyncWithResponseMessage(url, postData).ConfigureAwait(true))
{
if (response.IsSuccessStatusCode)
{
ret.Response = await response.Content.ReadAsStringAsync().ConfigureAwait(true);
ret.ContentType = response.Content.Headers.ContentType.ToString();
}
ret.StatusCode = response.StatusCode.ToInt();
}
采取这一行,在一个时间:
await client.PostAsyncWithResponseMessage(url, postData).ConfigureAwait(true))
这看起来是一个异步方法,但“客户”是我们的模仿对象所以它所做的只是支持IHttpClient接口。如果您检查线程,则在执行此行时ID不会更改。
后来,我们有:
await response.Content.ReadAsStringAsync().ConfigureAwait(true);
现在,这条线执行时,该HttpContext.Current设置为null - 我们所有的上下文丢弃。在这个应用程序中,我们不会在任何地方调用ConfigureAwait(false),所以据我所知,我们没有理由失去上下文。
如果我改变该行:
response.Content.ReadAsStringAsync().Result;
那么这当然是阻塞的,我们不会失去上下文。
所以两个问题:
- 为什么会await方法()ConfigureAwait(真)失去语境? [当然,如果人们也可以提出为什么来自一个TFS分支的同一代码在不同分支中工作时失败,但是我不期待],那么当然会获得更多的分数[
- 我可以看到等待.PostAsyncWithResponseMessage (url,postData)方法,因为当其他服务器处理我们的请求时,我们的线程会被阻塞。但是,检索数据后,在等待ReadAsStringAsync()...中有什么好处,换句话说,有没有很好的理由而不是使用.Result语法?
感谢
https://msdn.microsoft.com/en-us/magazine/jj991977.aspx – Nkosi
@Nkosi:我对这篇伟大的文章相当熟悉,并相信我们遵循所有已声明的最佳实践。请您指出我建议我阅读的这篇文章的具体部分。谢谢 – DrGriff