web-dev-qa-db-fra.com

Créer une tâche terminée <T>

J'implémente une méthode Task<Result> StartSomeTask() et je connais déjà le résultat avant d'appeler la méthode. Comment créer un Tâche <T> qui a déjà été terminé?

Voici ce que je fais actuellement:

private readonly Result theResult = new Result();

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

Y a-t-il une meilleure solution?

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

Lorsque vous ciblez .NET 4.5, vous pouvez utiliser Task.FromResult :

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

Pour créer une tâche ayant échoué, utilisez Task.FromException :

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

.NET 4.6 ajoute Task.CompletedTask si vous avez besoin d'un Task non générique.

public static Task CompletedTask { get; }

Solutions de contournement pour les anciennes versions de .NET:

  • Lorsque vous ciblez .NET 4.0 avec Async Targetting Pack (ou AsyncCTP), vous pouvez utiliser TaskEx.FromResult À la place.

  • Pour obtenir un Task non générique avant .NET 4.6, vous pouvez utiliser le fait que Task<T> Dérive de Task et appeler simplement Task.FromResult<object>(null) ou Task.FromResult(0).

193
CodesInChaos

Pour les tâches sans valeur de retour, .NET 4.6 a ajouté Task.CompletedTask .

Il renvoie une tâche qui est déjà dans TaskStatus.RanToCompletion. Il renvoie probablement la même instance à chaque fois, mais la documentation vous avertit de ne pas compter sur ce fait.

12
Daryl

Appel de Task.WhenAll sans aucun paramètre renverra une tâche terminée.

Task task = Task.WhenAll();
1
zumalifeguard

Si vous utilisez Rx, une alternative est Observable.Return (result) .ToTask ().

1