HttpContext.Currentに大きく依存する古いライブラリを使用する必要があるASP.NetでホストされるWebAPIサービスのセットを構築しています。非同期呼び出しに参加するすべてのメソッドでコンテキストが保持されるようにするのに問題があります。以下のコードでawait/Task.WaitとTaskScheduler.FromCurrentSynchronizationContext()を使用していくつかのバリエーションを試しました。
[HttpGet]
public Task<IEnumerable<string>> ContinueWith()
{
Thread.CurrentThread.CurrentCulture = new CultureInfo("fr-FR"); //or another culture that is not the default on your machine
Thread.CurrentThread.CurrentUICulture = Thread.CurrentThread.CurrentCulture;
var output = new List<string> { TestOutput("Action start") };
var task = Task.Factory.StartNew(() =>
{
Thread.Sleep(1000);
return TestOutput("In Task");
}).ContinueWith(slowString =>
{
output.Add(slowString.Result);
output.Add(TestOutput("Action end"));
return output as IEnumerable<string>;
});
output.Add(TestOutput("Action Mid"));
return task;
}
private string TestOutput(string label)
{
var s = label + " ThreadID: " + Thread.CurrentThread.ManagedThreadId.ToString(CultureInfo.InvariantCulture);
s += " " + Thread.CurrentThread.CurrentCulture.EnglishName;
s += HttpContext.Current == null ? " No Context" : " Has Context";
Debug.WriteLine(s);
return s;
}
CurrentCultureがfr-FRであり、TestOutputが呼び出される各ポイントでHttpContext.Currentがnullでないことを確認できるようにしたいと思います。私が試したことは何でも、「タスク中」の呼び出しでそれを行うことに成功していません。また、一部のテストスレッドIDは変化せず、メソッドの非同期性を効果的に削除したことを示しています。TestOutputを呼び出すたびに、カルチャとHttpContext.Currentが保持され、コードがさまざまなスレッドで自由に実行できるようにするにはどうすればよいですか?
クロージャーでHttpContext.Currentをキャプチャしてから再度設定するだけでは、HttpContext.Currentセッターを呼び出すときにセキュリティ例外をスローするMedium Trustをサポートする必要があるため、機能しません。