非同期な ASP.NET MVC で HttpContext.Current を使うのはやめた方がいい、という話。
[非同期メソッドのサンプル]
上記で HttpContext.Current が使用できるのは (A) (B) (C) のどこか?
と疑問になったので調査してみた。
[結果]
※ Windows 7/IIS 7.5/ASP.NET MVC 5/.NET 4.5.2
※ Visual Studio 付属の IIS Express は異なる結果になる場合あり
ちなみに、真ん中の Task を ConfigureAwait(false) とすると、設定に関わらず (C) でも HttpContext.Current 使用不可。
そもそも ASP.NET MVC の Controller クラスには HttpContext プロパティがあるので、これを使うのが普通。
Controller から呼び出すロジッククラスでは、HttpContext を引数渡しで使うのが無難。コードが増えるけど・・・
当たり前だけど HttpContext クラスにできるだけ依存しないクラス設計が大事。
[非同期メソッドのサンプル]
public class MyController : Controller
{
// RouteConfig で URL が割り当てられた非同期メソッド
public async Task<ActionResult> Test()
{
// (A)
await Task.Run(() => {
// (B)
});
// (C)
return View();
}
}
上記で HttpContext.Current が使用できるのは (A) (B) (C) のどこか?
と疑問になったので調査してみた。
[結果]
(A) | 使用可能 |
---|---|
(B) | 使用不可 |
(C) |
web.config の設定で変わる <appSettings> に <add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" /> を設定、または、<system.web> に <httpRuntime targetFramework="4.5"> (4.5 以上なら OK) を設定すると使用可能 上記を設定してない場合は使用不可 |
※ Visual Studio 付属の IIS Express は異なる結果になる場合あり
ちなみに、真ん中の Task を ConfigureAwait(false) とすると、設定に関わらず (C) でも HttpContext.Current 使用不可。
まとめ
調査結果のとおりなのだが、非同期だと HttpContext.Current は設定やコードに依存して使えたり使えなかったりするので、使わない方がまし・・・使用禁止でもいいと思う。そもそも ASP.NET MVC の Controller クラスには HttpContext プロパティがあるので、これを使うのが普通。
Controller から呼び出すロジッククラスでは、HttpContext を引数渡しで使うのが無難。コードが増えるけど・・・
当たり前だけど HttpContext クラスにできるだけ依存しないクラス設計が大事。
0 件のコメント:
コメントを投稿