Create a completed Task<T>
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?
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 thatTask<T>
derives fromTask
and just callTask.FromResult<object>(null)
orTask.FromResult(0)
.
private readonly Result theResult = new Result();
public override Task<Result> StartSomeTask()
{
var taskSource = new TaskCompletionSource<Result>();
taskSource.SetResult(theResult);
return taskSource.Task;
}
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().