.NET の非同期機能を少しいじっていたところ、うまく説明できない状況に遭遇しました。同期 ASP.NET MVC コントローラー内で次のコードを実行する場合
var t = Task.Factory.StartNew(()=>{
var ctx = System.Web.HttpContext.Current;
//ctx == null here
},
CancellationToken.None,
TaskCreationOptions.None,
TaskScheduler.FromCurrentSynchronizationContext()
);
t.Wait();
ctx
null
デリゲート内にあります。私の理解では、TaskScheduler.FromCurrentSynchronizationContext()
タスクスケジューラを使用するときにコンテキストを復元する必要があります。では、なぜここにいないのでしょうか。(ところで、デリゲートが同じスレッドで同期的に実行されることがわかります)。
また、msdnから、 aTaskScheduler.FromCurrentSynchronizationContext()
は次のように動作する必要があります。
返されたスケジューラのキューに入れられたすべての Task インスタンスは、そのコンテキストで Post メソッドを呼び出すことによって実行されます。
ただし、このコードを使用すると:
var wh = new AutoResetEvent(false);
SynchronizationContext.Current.Post(s=> {
var ctx = System.Web.HttpContext.Current;
//ctx is set here
wh.Set();
return;
},null);
wh.WaitOne();
コンテキストは実際に設定されています。
この例が少し不自然であることは承知していますが、.NET での非同期プログラミングの理解を深めるために何が起こるかを理解したいと思っています。