我正在实现一个方法Task<Result> StartSomeTask()
,并且在调用该方法之前就已经知道了结果。如何创建已完成的Task<T>?
这就是我目前正在做的事情:
private readonly Result theResult = new Result();
public override Task<Result> StartSomeTask()
{
var task = new Task<Result>(() => theResult);
task.RunSynchronously(CurrentThreadTaskScheduler.CurrentThread);
return task;
}
有更好的解决方案吗?
答案 0 :(得分:183)
以.NET 4.5为目标时,您可以使用Task.FromResult
:
public static Task<TResult> FromResult<TResult>(TResult result);
要创建失败的任务,请使用Task.FromException
:
public static Task FromException(Exception exception);
public static Task<TResult> FromException<TResult>(Exception exception);
如果您需要非通用Task
, .NET 4.6会添加Task.CompletedTask
。
public static Task CompletedTask { get; }
旧版.NET的解决方法:
使用Async Targetting Pack(或AsyncCTP)定位.NET 4.0时,您可以改为使用TaskEx.FromResult
。
要在.NET 4.6之前获取非通用Task
,您可以使用Task<T>
派生自Task
的事实,只需调用Task.FromResult<object>(null)
或{ {1}}。
答案 1 :(得分:108)
private readonly Result theResult = new Result();
public override Task<Result> StartSomeTask()
{
var taskSource = new TaskCompletionSource<Result>();
taskSource.SetResult(theResult);
return taskSource.Task;
}
答案 2 :(得分:12)
对于没有返回值的任务,.NET 4.6添加了Task.CompletedTask。
它返回一个已在TaskStatus.RanToCompletion中的任务。它可能每次都返回相同的实例,但是文档警告你不要指望这个事实。
答案 3 :(得分:1)
如果您正在使用Rx,则替代方案是Observable.Return(result).ToTask()。
答案 4 :(得分:1)
调用Task.WhenAll没有任何参数将返回已完成的任务。
Task task = Task.WhenAll();
答案 5 :(得分:0)
你可以试试var myAlreadyCompletedTask = Task.FromResult<string>("MyValue")
这将为您提供具有指定返回类型的任务