I'm implementing a method Task<Result> StartSomeTask()
and happen to know the result already before the method is called. How do I create a Task<T> that has already completed?
This is what I'm currently doing:
private readonly Result theResult = new Result();
public override Task<Result> StartSomeTask()
{
var task = new Task<Result>(() => theResult);
task.RunSynchronously(CurrentThreadTaskScheduler.CurrentThread);
return task;
}
Is there a better solution?
private readonly Result theResult = new Result();
public override Task<Result> StartSomeTask()
{
var taskSource = new TaskCompletionSource<Result>();
taskSource.SetResult(theResult);
return taskSource.Task;
}
When targeting .NET 4.5 you can use Task.FromResult
:
public static Task<TResult> FromResult<TResult>(TResult result);
To create a failed task, use Task.FromException
:
public static Task FromException(Exception exception);
public static Task<TResult> FromException<TResult>(Exception exception);
.NET 4.6 adds Task.CompletedTask
if you need a non generic Task
.
public static Task CompletedTask { get; }
Workarounds for older versions of .NET:
When targeting .NET 4.0 with Async Targetting Pack (or AsyncCTP) you can use TaskEx.FromResult
instead.
To get non-generic Task
prior to .NET 4.6, you can use the fact that Task<T>
derives from Task
and just call Task.FromResult<object>(null)
or Task.FromResult(0)
.
For tasks with no return value, .NET 4.6 has added Task.CompletedTask.
It returns a task which is already in TaskStatus.RanToCompletion. It probably returns the same instance every time, but the documentation warns you not to count on that fact.
If you're using Rx, an alternative is Observable.Return(result).ToTask().
Calling Task.WhenAll without any parameters will return a completed task.
Task task = Task.WhenAll();