Erstellen Sie eine abgeschlossene Aufgabe
-
27-09-2019 - |
Frage
Ich bin Implementierung eines Verfahrens Task<Result> StartSomeTask()
und passieren das Ergebnis bereits kennen, bevor die Methode aufgerufen wird. Wie erstelle ich eine Aufgabe
Das ist, was ich derzeit tue:
private readonly Result theResult = new Result();
public override Task<Result> StartSomeTask()
{
var task = new Task<Result>(() => theResult);
task.RunSynchronously(CurrentThreadTaskScheduler.CurrentThread);
return task;
}
Gibt es eine bessere Lösung?
Lösung
private readonly Result theResult = new Result();
public override Task<Result> StartSomeTask()
{
var taskSource = new TaskCompletionSource<Result>();
taskSource.SetResult(theResult);
return taskSource.Task;
}
Andere Tipps
Wenn .NET 4.5-Targeting können Sie verwenden Task.FromResult
:
public static Task<TResult> FromResult<TResult>(TResult result);
ein ausgefallenes Aufgabe zu erstellen, verwenden Task.FromException
:
public static Task FromException(Exception exception);
public static Task<TResult> FromException<TResult>(Exception exception);
.NET 4.6 fügt Task.CompletedTask
wenn Sie einen nicht generischen Task
benötigen.
public static Task CompletedTask { get; }
Umgehungen für ältere Versionen von .NET:
-
Wenn .NET 4.0 mit Async Targetting-Pack (oder AsyncCTP) Targeting Sie
TaskEx.FromResult
stattdessen verwenden können. -
Um nicht-generic
Task
vor .NET 4.6 können Sie die Tatsache nutzen, dassTask<T>
ergibt sich ausTask
und einfach AufrufTask.FromResult<object>(null)
oderTask.FromResult(0)
.
Für Aufgaben ohne Rückgabewert, .NET 4.6 hinzugefügt Aufgabe .CompletedTask .
Es gibt eine Aufgabe, die bereits in TaskStatus.RanToCompletion ist. Wahrscheinlich gibt die gleiche Instanz jedes Mal, aber die Dokumentation warnt Sie nicht auf diese Tatsache zu zählen.
Wenn Sie Rx verwenden, eine Alternative ist Observable.Return (Ergebnis) .ToTask ().
Der Aufruf Task.WhenAll ohne Parameter wird eine erledigte Aufgabe zurück.
Task task = Task.WhenAll();