web-dev-qa-db-ja.com

完了したタスクを作成する<T>

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

これは私が現在やっていることです:

private readonly Result theResult = new Result();

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

より良い解決策はありますか?

117
dtb
private readonly Result theResult = new Result();

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

.NET 4.5を対象とする場合、 Task.FromResult を使用できます。

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が必要な場合は Task.CompletedTask が追加されます。

public static Task CompletedTask { get; }

古いバージョンの.NETの回避策:

  • Async Targetting Pack(またはAsyncCTP)で.NET 4.0をターゲットにする場合、代わりにTaskEx.FromResultを使用できます。

  • .NET 4.6より前の非ジェネリックTaskを取得するには、Task<T>Taskから派生し、Task.FromResult<object>(null)またはTask.FromResult(0)

193
CodesInChaos

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

既にTaskStatus.RanToCompletionにあるタスクを返します。おそらく毎回同じインスタンスを返しますが、ドキュメントではその事実に頼らないように警告しています。

12
Daryl

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

Task task = Task.WhenAll();
1
zumalifeguard

Rxを使用している場合、代替手段はObservable.Return(result).ToTask()です。

1