Create a completed Task<T>
C#.NetTask Parallel-LibraryC# Problem Overview
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?
C# Solutions
Solution 1 - C#
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)
.
Solution 2 - C#
private readonly Result theResult = new Result();
public override Task<Result> StartSomeTask()
{
var taskSource = new TaskCompletionSource<Result>();
taskSource.SetResult(theResult);
return taskSource.Task;
}
Solution 3 - C#
For tasks with no return value, .NET 4.6 has added [Task.CompletedTask][1].
It returns a task which is already in state TaskStatus.RanToCompletion
. It probably returns the same instance every time, but the documentation warns you not to count on that fact.
[1]: https://msdn.microsoft.com/en-us/library/system.threading.tasks.task.completedtask.aspx "Task.CompletedTask on MSDN"
Solution 4 - C#
If you're using Rx, an alternative is Observable.Return(result).ToTask().
Solution 5 - C#
Calling Task.WhenAll without any parameters will return a completed task.
Task task = Task.WhenAll();
Solution 6 - C#
You can try var myAlreadyCompletedTask = Task.FromResult<string>("MyValue")
This will give you a task with a specified return type