完成したTask
(ではないTask<T>
)を作成したい。これを行うために.NETに組み込まれているものはありますか?
関連質問: 完了したタスクを作成する<T>
ValueTask
、完了したタスク(つまり、コードが基本的に同期するように既に持っている値)があるため、割り当てを節約できることに注意してください。
完成したTask
(ではないTask<T>
)を作成したい。これを行うために.NETに組み込まれているものはありますか?
関連質問: 完了したタスクを作成する<T>
ValueTask
、完了したタスク(つまり、コードが基本的に同期するように既に持っている値)があるため、割り当てを節約できることに注意してください。
回答:
.Net(v4.6)の最新バージョンは、組み込みのTask.CompletedTaskだけを追加しています。
Task completedTask = Task.CompletedTask;
そのプロパティはロックなしのシングルトンとして実装されているため、ほとんどの場合、同じ完了したタスクを使用します。
Task.CompletedTask
まだ内部にあります。
Task<T>
は暗黙的にに変換できるTask
ので、Task<T>
(T
任意の値と任意の値で)完了してそれを使用するだけです。このようなものを使用して、実際の結果がどこかにあるという事実を隠すことができます。
private static Task completedTask = Task.FromResult(false);
public static Task CompletedTask()
{
return completedTask;
}
結果を公開しておらず、タスクは常に完了しているため、単一のタスクをキャッシュして再利用できます。
.NET 4.0を使用していてFromResult
、それがない場合は、次のコマンドを使用して独自に作成できますTaskCompletionSource
。
public static Task<T> FromResult<T>(T value)
{
var tcs = new TaskCompletionSource<T>();
tcs.SetResult(value);
return tcs.Task;
}
これを行うための私の好ましい方法はTask.WhenAll()
、引数なしで呼び出すことです。MSDNのドキュメントの状態「付属の配列/列挙は何のタスクが含まれていない場合、返されたタスクは、それが呼び出し元に返される前RanToCompletion状態にすぐに移行します。」という。それはあなたが望むもののように聞こえます。
更新:ソースはMicrosoftのReference Sourceで見つかりました。そこでTask.WhenAllに以下が含まれていることがわかります。
return (tasks.Length == 0) ? // take shortcut if there are no tasks upon which to wait
Task.CompletedTask :
new WhenAllPromise(tasks);
したがって、Task.CompletedTaskは確かに内部にありますが、引数なしでWhenAll()を呼び出すことによって公開されます。
Task.FromResult(.NET 4.5)を使用して、完了したを返すことができますTask<T>
。
非ジェネリックが必要な場合は、のサブクラスなので、Task
いつでもTask.FromResult(0)
または同様に使用できます。Task<T>
Task
Stephen ClearyのすばらしいライブラリAsyncExからNito.AsyncEx.TaskConstants.Completedを使用できます。
どうですか:
#pragma warning disable 1998
public async Task emptyTask() {
}
#pragma warning restore 1998
気にならない場合は、警告の抑制を省略できます。
async
すると、それを使用しなくてもステートマシン装置全体が作成されると思います。したがって、リソースが少ないシナリオでは、空のタスクを返す方が効率的です。
It seems like the answer I'm getting from everyone is that using a garbage value like this is the correct way. That there isn't a way to do this without the garbage value is disappointing -- oh well.
これにはどのような問題があると思いますか?シングルをキャッシュするとTask
、プログラム全体で1ビット余分にメモリを消費します。それは何でもない。また、それを実行せずに完了したタスクを作成することもできます。