15

以下は、UI スレッド ( WindowsFormsSynchronizationContextを使用)で実行されるコードのTest_Click簡略化されたバージョンです。

void Test_Click(object sender, EventArgs e)
{
    var task = DoNavigationAsync();
    task.ContinueWith((t) =>
    {
        MessageBox.Show("Navigation done!");
    }, TaskScheduler.FromCurrentSynchronizationContext());
}

TaskScheduler.FromCurrentSynchronizationContext()継続アクションが同じ UI スレッドで実行されるように明示的に指定する必要がありますか? またはContinueWith、実行コンテキストを自動的にキャプチャしますか (したがって、TaskSchedulerこの場合、引数を冗長にします)?

デフォルトでは(とは異なり)それを行わないと思いますawaitが、これまでのところ、これを確認するためのオンラインリソースを見つけることができませんでした.

4

1 に答える 1

10

デフォルトでは現在の同期コンテキストを使用しませんがTaskScheduler.Current、次の逆コンパイルされたコードに見られるように:

public Task ContinueWith(Action<Task<TResult>> continuationAction)
{
  StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
  return this.ContinueWith(continuationAction, TaskScheduler.Current, new CancellationToken(), TaskContinuationOptions.None, ref stackMark);
}

TaskScheduler.CurrentまたはTaskScheduler.Default、タスクが子タスクの場合、現在のタスクの TaskScheduler です。奇妙な問題に遭遇したくない場合は、常にタスクスケジューラを指定するか、可能であれば使用しawaitてください。

于 2013-08-19T11:51:17.867 に答える