私は次のテストWebAPIコードを持っています。本番環境ではWebAPIを使用しませんが、この質問に関する議論のために作成しました: WebAPI Async question
とにかく、問題のある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
は、待ってから解決するはずです。この質問には、同じことを示す別のコメントもあります。それでは本当ですか?解決すべきですか?いいえと思いますが、async
とawait
は十分に新しいので、決定的なものを見つけることができないので、これに関する信頼できる答えが欲しいです。
TL; DR:HttpContext.Current
潜在的にnull
の後にawait
?
ASP.NET4.5アプリケーションを作成し、4.5をターゲットにしていることを確認してください。 async
およびawait
は、4.5およびで実行している場合を除き、ASP.NETで未定義の動作を持ち、新しい "タスクフレンドリーな」同期コンテキスト。
特に、これは次のいずれかを行う必要があることを意味します。
httpRuntime.targetFramework
を4.5
に設定する、またはappSettings
で、aspnet:UseTaskFriendlySynchronizationContext
をtrue
に設定します。詳細は こちらから入手可能 です。
@StephenClearyが正しく指摘したように、web.configでこれが必要です。
<httpRuntime targetFramework="4.5" />
最初にこれをトラブルシューティングするときに、上記のソリューション全体を検索し、すべてのWebプロジェクトに存在することを確認し、犯人としてすぐに却下しました。最終的に、これらの検索結果を完全なコンテキストで見ることになりました。
<!--
For a description of web.config changes for .NET 4.5 see http://go.Microsoft.com/fwlink/?LinkId=235367.
The following attributes can be set on the <httpRuntime> tag.
<system.Web>
<httpRuntime targetFramework="4.5" />
</system.Web>
-->
ど.
レッスン:Webプロジェクトを4.5にアップグレードする場合、その設定を手動で適切に行う必要があります。
私のテストに欠陥がありますか、それともここで欠落しているweb.config要素があり、それによりHttpContext.Currentが待機後に正しく解決されますか?
テストに欠陥はなく、待機後のHttpContext.Currentはnullであってはなりません。ASP.NETWeb APIでは待機するときに、これにより、この待機に続くコードに待機前に存在していた正しいHttpContextが渡されます。