创建一个已完成的任务<T>

dtb*_*dtb 118 .net c# task-parallel-library

我正在实现一个方法,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;
}
Run Code Online (Sandbox Code Playgroud)

有更好的解决方案吗?

Cod*_*aos 197

以.NET 4.5为目标时,您可以使用Task.FromResult:

public static Task<TResult> FromResult<TResult>(TResult result);
Run Code Online (Sandbox Code Playgroud)

要创建失败的任务,请使用Task.FromException:

public static Task FromException(Exception exception);
public static Task<TResult> FromException<TResult>(Exception exception);
Run Code Online (Sandbox Code Playgroud)

Task.CompletedTask如果您需要非泛型,则.NET 4.6会添加Task.

public static Task CompletedTask { get; }
Run Code Online (Sandbox Code Playgroud)

旧版.NET的变通方法:

  • 使用异步目标包(或AsyncCTP)定位.NET 4.0时,您可以使用TaskEx.FromResult.

  • Task在.NET 4.6之前获得非泛型,您可以使用Task<T>派生自Task且只调用Task.FromResult<object>(null)或的事实Task.FromResult(0).

  • 要返回非泛型任务,最好使用Task.FromResult(0)之类的东西.使用"null"作为参数可能会混淆无法确定通用参数的编译器. (13认同)

Qry*_*taL 109

private readonly Result theResult = new Result();

public override Task<Result> StartSomeTask()
{
    var taskSource = new TaskCompletionSource<Result>();
    taskSource.SetResult(theResult);
    return taskSource.Task;
}
Run Code Online (Sandbox Code Playgroud)

  • 难道不应该是下面那个更简单并且有更多赞成票的吗?@用户2023861 (2认同)

Dar*_*ryl 12

对于没有返回值的任务,.NET 4.6添加了Task.CompletedTask.

它返回一个已在TaskStatus.RanToCompletion中的任务.它可能每次返回相同的实例,但文档警告您不要指望这个事实.