失います。あるブランチから別のブランチにコードをマージして、新しいブランチの一部のインテグレーションテストがSystem.NullReferenceExceptionのために失敗することがわかりました。私は両方のブランチで私たちのコードが同一であり、参照されているすべてのDLLも同じであることを保証するために時間を費やしています。すべてが同じようです。待望非同期タスクは、私たちはTFSに2つの支店を持っている非同期HTTP POSTをを作るWebアプリケーションに関して非常に奇妙な状況...</p> <p>を持ってHttpContext.Current
私はテストをデバッグすることにしました。
私たちのテストは、Mock IHttpClientオブジェクトを作成することです。 clientMock.PostAsyncWithResponseMessage(x、y)が新しいHttpResponseMessage()オブジェクト(さまざまなプロパティを設定している)を返すように、Mockオブジェクトをスタブします。
ので、コードは次のようになります。
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;
次に、このコースのブロッキングのであり、我々はコンテキストを失うことはありません。
ので、2つの質問:。
- はなぜ()ConfigureAwait(真)のawaitメソッドは、コンテキストを失うことになりますか? [なぜなら、1つのTFSブランチの同じコードが別のブランチで作業しているのに失敗する理由を示唆してもいいと思うのですが、私はそれを期待していません。]
- .PostAsyncWithResponseMessage (url、postData)メソッドを使用していました。しかし、データを取得すると、ReadAsStringAsync()を待つのにどのような利点がありますか。つまり、ではなく、の.Result構文を使用するのがよい理由はありますか?あなたがスレッドを調べる場合は、この行を実行する際に、IDは変更されません
おかげ
https://msdn.microsoft.com/en-us/magazine/jj991977.aspx – Nkosi
@Nkosi:私はこの偉大な記事をよく知っており、宣言されているベストプラクティスに従っていると考えています。あなたが私が読んでいることを示唆しているこの記事の特定の部分を指摘してください。ありがとう – DrGriff