web-dev-qa-db-ja.com

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

完成したTaskTask<T>ではなく)を作成したい。これを行うために.NETに組み込まれているものはありますか?

関連する質問: 完了したタスク<T>を作成する

173
Timothy Shields

。Net(v4.6)の最新バージョン は、組み込みの Task.CompletedTask を追加しています。

Task completedTask = Task.CompletedTask;

そのプロパティはロックなしのシングルトンとして実装されるため、almostは常に同じ完了タスクを使用します。

219
i3arnon

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;
}
144
Servy

これを行うための好ましい方法は、Task.WhenAll()を引数なしで呼び出すことです。 MSDN documentation は、「提供された配列/列挙型にタスクが含まれていない場合、返されたタスクは呼び出し元に返される前にすぐにRanToCompletion状態に移行します」と述べています。それはあなたが望むもののように聞こえます。

更新: Microsoftの参照ソース ;でソースを見つけました。そこには、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()を呼び出すことで公開されます。

63
Richiban

Task.Delay(0)を使用します。内部的には、完了したTask<T>のキャッシュされたインスタンスを返します。これは、現在の答えがとにかく実行することを示唆しているものです。インスタンスを自分でキャッシュする必要も、コードに不要なガベージ値もありません。

代わりにTask.Yield()を使用できると考えているかもしれませんが、Task.Yield()の結果はnotのサブタイプTaskですが、Task.Delay(0)です。これは、2つの微妙な違いの1つです。

33
gzak

Task.FromResult (.NET 4.5)を使用して、完了したTask<T>を返すことができます。

非ジェネリックTaskが必要な場合は、Task<T>Taskのサブクラスであるため、常にTask.FromResult(0)などを使用できます。

29
Reed Copsey

.Net 4.6以降の使用

return Task.CompletedTask;

下位バージョンの場合は、使用できます

return new Task(() => { });
8
Icen

素晴らしいライブラリから Nito.AsyncEx.TaskConstants.Completed を使用できます AsyncEx from Stephen Cleary

8

どうですか:

#pragma warning disable 1998
    public async Task emptyTask() {
    }
#pragma warning restore 1998

気にしない場合は、警告抑制を省略できます。

0
Dorus