创建一个完成的任务

Tim*_*lds 181 .net c# task-parallel-library async-await

我想创建一个完整的Task(不是Task<T>)..NET中是否有内置功能可以执行此操作?

相关问题: 创建已完成的任务<T>

i3a*_*non 231

净(V4.6)的最新版本仅仅是添加,内置Task.CompletedTask:

Task completedTask = Task.CompletedTask;
Run Code Online (Sandbox Code Playgroud)

该属性实现为无锁单例,因此您几乎总是使用相同的已完成任务.

  • 刚刚检查了最新的 VS 14 CTP 并创建了一个 4.5.3 项目,`Task.CompletedTask` 仍然是内部的。 (2认同)

Ser*_*rvy 147

Task<T>可以隐式转换为Task,所以只需要完成Task<T>(使用任何T和任何值)并使用它.你可以使用这样的东西来隐藏某个地方存在实际结果的事实.

private static Task completedTask = Task.FromResult(false);
public static Task CompletedTask()
{
    return completedTask;
}
Run Code Online (Sandbox Code Playgroud)

请注意,由于我们没有公开结果,并且任务总是完成,因此我们可以缓存单个任务并重用它.

如果您使用的是.NET 4.0而没有,FromResult那么您可以使用TaskCompletionSource以下方法创建自己的:

public static Task<T> FromResult<T>(T value)
{
    var tcs = new TaskCompletionSource<T>();
    tcs.SetResult(value);
    return tcs.Task;
}
Run Code Online (Sandbox Code Playgroud)

  • 如果您使用的是4.0,则可以添加Microsoft.Bcl.Async库以获取TaskEx.FromResult,以及其他方便的内容,如WhenAll (8认同)
  • @FrancescoB。如果您正在查看结果,那么它将更改结果的布尔值。如果您忽略结果,那么结果是无关紧要的。 (2认同)

Ric*_*ban 64

我这样做的首选方法是Task.WhenAll()不带参数调用.在MSDN文档指出,"如果提供的阵列/枚举不包含任何任务,返回的任务将立即之前它返回给调用者过渡到RanToCompletion状态." 这听起来像你想要的.

更新:我在Microsoft的Reference Source找到了源代码 ; 在那里你可以看到Task.WhenAll包含以下内容:

return (tasks.Length == 0) ? // take shortcut if there are no tasks upon which to wait
            Task.CompletedTask :
            new WhenAllPromise(tasks);
Run Code Online (Sandbox Code Playgroud)

所以Task.CompletedTask确实是内部的,但它是通过调用没有参数的WhenAll()来公开的.

  • 虽然它感觉有点hacky,它得到了文档的支持,所以我不知道,我有点喜欢它! (8认同)
  • 对我和我的 .NET 4.5.2 约束代码来说,它已经足够优雅了。谢谢! (2认同)

gza*_*zak 34

我会用Task.Delay(0).在内部,它返回已完成的缓存实例Task<T>.这正是当前答案建议做的事情,只是现在你不必自己缓存一个实例,你的代码中也没有任何不优雅的垃圾值.

你可能会想,你可以使用Task.Yield(),而不是,但事实证明,结果Task.Yield()没有的一个亚型Task,而结果Task.Delay(0)是.这是两者之间微妙的差异之一.


Ree*_*sey 29

您可以使用Task.FromResult(在.NET 4.5中)返回已完成的内容Task<T>.

如果你需要一个非泛型的Task,你总是可以使用Task.FromResult(0)或者类似,因为它Task<T>是一个子类Task.


Ice*_*cen 9

适用于.Net 4.6及以上版本

return Task.CompletedTask;
Run Code Online (Sandbox Code Playgroud)

对于较低版本,您可以使用

return new Task(() => { });
Run Code Online (Sandbox Code Playgroud)

  • 对于4.6之前的方法,请小心!您需要启动任务,否则它将永远无法完成!改用`return Task.Delay(0);`怎么样? (2认同)