46

Task<T>私は自由にできるいくつかのメソッドを返しawaitます。TaskSchedulerこれらのタスクをデフォルトではなくカスタムで実行したいと思います。

var task = GetTaskAsync ();
await task;

新しい を作成TaskFactory (new CustomScheduler ())し、StartNew ()そこから を実行できることはわかっていStartNew ()ますが、アクションを実行して を作成しTask、すでに を持っていますTask(舞台裏で によって返されますTaskCompletionSource) 。

に独自のものを指定するにはどうすればよいTaskSchedulerですawaitか?

4

6 に答える 6

51

あなたが本当にしたいのはTask.Run、カスタムスケジューラを使用することだと思います。StartNew非同期メソッドでは直感的に機能しません。Stephen Toub は、との違いTask.RunTaskFactory.StartNewについて素晴らしいブログ投稿をしています。

したがって、独自の custom を作成するには、次のRunようにします。

private static readonly TaskFactory myTaskFactory = new TaskFactory(
    CancellationToken.None, TaskCreationOptions.DenyChildAttach,
    TaskContinuationOptions.None, new MyTaskScheduler());
private static Task RunOnMyScheduler(Func<Task> func)
{
  return myTaskFactory.StartNew(func).Unwrap();
}
private static Task<T> RunOnMyScheduler<T>(Func<Task<T>> func)
{
  return myTaskFactory.StartNew(func).Unwrap();
}
private static Task RunOnMyScheduler(Action func)
{
  return myTaskFactory.StartNew(func);
}
private static Task<T> RunOnMyScheduler<T>(Func<T> func)
{
  return myTaskFactory.StartNew(func);
}

その後、カスタム スケジューラで同期または非同期メソッドを実行できます。

于 2013-03-15T12:08:33.263 に答える
4

コメントの後、await の後のコードが実行されるスケジューラを制御したいようです。

コンパイルは、デフォルトで現在の SynchronizationContext で実行される await から継続を作成します。SynchronizationContextしたがって、最善の方法は、電話をかける前に awaitを設定することです。

特定のコンテキストを待機する方法はいくつかあります。このようなものを実装する方法の詳細については、Jon Skeet のConfigure Await、特に SwitchTo に関する部分を参照してください。

編集: TaskEx の SwitchTo メソッドは、誤用しやすいため削除されました。理由については、 MSDN フォーラムを参照してください。

于 2013-03-15T10:14:35.833 に答える
3

このメソッド呼び出しに適合できますか:

  await Task.Factory.StartNew(
        () => { /* to do what you need */ }, 
        CancellationToken.None, /* you can change as you need */
        TaskCreationOptions.None, /* you can change as you need */
        customScheduler);
于 2014-04-30T09:52:56.287 に答える