次のコードを見てください。
そこで、現在のコンテキスト (WinForms スレッド) を取得し、そのコンテキストで新しいタスクを開始し、タスク スケジューラで同期継続をアタッチしDefault
ます。私が理解している限り、継続はスレッドプールスレッドで開始する必要があります。UI スレッドがスレッドプールに属していません。しかし、代わりに、継続を含むすべてのコードが同じスレッドで同期して実行されます。それは私にとってかなり予想外です。
ところで、継続オプションを に設定すると、必要にTaskContinuationOptions.None
応じて別のスレッドで実行されます。継続オプションはタスク スケジューラよりも優先されるようですが、それらは単なるヒントであり、スケジューラは必須です。
TaskScheduler uiContext = TaskScheduler.FromCurrentSynchronizationContext();
Console.WriteLine("start thread {0}", Thread.CurrentThread.ManagedThreadId);
Task.Factory.StartNew(() =>
{
Console.WriteLine("ui thread {0}", Thread.CurrentThread.ManagedThreadId);
}, CancellationToken.None, TaskCreationOptions.None, uiContext).ContinueWith(t =>
{
Console.WriteLine("continuation thread {0}", Thread.CurrentThread.ManagedThreadId);
}, CancellationToken.None, TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default);
それはバグですか、それとも予想される動作ですか?
親タスクのコンテキストと継続オプションに関係なく、UI スレッドの外部で継続コードの実行を保証するにはどうすればよいですか? カスタムタスクスケジューラ?
注: これがレガシー コードであることはわかっており、async/await を使用することをお勧めします。