2010-11-22 13 views
100

私はメソッドTask<Result> StartSomeTask()を実装していて、メソッドが呼び出される前にその結果を知っています。すでに完了しているTask<T>を作成するにはどうすればよいですか?完了したタスクを作成する<T>

private readonly Result theResult = new Result(); 

public override Task<Result> StartSomeTask() 
{ 
    var task = new Task<Result>(() => theResult); 
    task.RunSynchronously(CurrentThreadTaskScheduler.CurrentThread); 
    return task; 
} 

よりよい解決策があります:

これは私が現在やっているのですか?

+6

注、この質問に対する答えは、タスクからタスク継承するため、プレーンタスク(なし)を作成するためにうまく動作します。 –

答えて

102
private readonly Result theResult = new Result(); 

public override Task<Result> StartSomeTask() 
{ 
    var taskSource = new TaskCompletionSource<Result>(); 
    taskSource.SetResult(theResult); 
    return taskSource.Task; 
} 
162

あなたがTask.FromResultを使用することができます.NET 4.5をターゲット:

public static Task<TResult> FromResult<TResult>(TResult result); 

失敗したタスクを作成するには、Task.FromExceptionを使用する:あなたは非が必要な場合

public static Task FromException(Exception exception); 
public static Task<TResult> FromException<TResult>(Exception exception); 

.NET 4.6は、Task.CompletedTaskを追加します汎用Task。 .NETの古いバージョンのための

public static Task CompletedTask { get; } 

回避策:

  • 非同期ターゲッティングパック(またはAsyncCTP)と.NET 4.0をターゲットにする場合は、代わりにTaskEx.FromResultを使用することができます。非ジェネリックTask前に.NET 4.6に到達するために

  • 、あなたはTask<T>Taskから派生し、ちょうど​​またはTask.FromResult(0)を呼ぶという事実を使用することができます。

+13

ジェネリックでないタスクを返すには、Task.FromResult(0)のようなものを使うのが良いでしょう。 "null"をパラメータとして使用すると、汎用パラメータを特定できないコンパイラが混乱する可能性があります。 – Whyllee

+0

例外についてはどうですか?非同期メソッドは、例外をキャッチして返されたタスクに保存するステートマシンにコンパイルされます。これは、最初に待つ前に実行されているコードでも発生します。 Task.FromResultを返すメソッドは、例外を直接スローする可能性があります。 –

+0

@RobertVažan興味深いケースです。おそらく、メソッドから_known result_を取得していて、そのメソッドが例外をスローすると、修正が必要な不具合があります。 – Gusdor

1

Rxを使用している場合は、代わりにObservable.Return(result).ToTask()を使用します。

12

戻り値のないタスクの場合、.NET 4.6にはTask.CompletedTaskが追加されました。

TaskStatus.RanToCompletionに既にあるタスクを返します。たぶん毎回同じインスタンスを返しますが、ドキュメンテーションはあなたにその事実を数えないよう警告します。

0

パラメータを指定しないでTask.WhenAllを呼び出すと、完了したタスクが返されます。

Task task = Task.WhenAll(); 
関連する問題