我想创建一个已完成的任务(不是任务<T>)。net中是否内置了一些功能来实现这一点?
一个相关的问题: 创建一个已完成的任务<T>
我想创建一个已完成的任务(不是任务<T>)。net中是否内置了一些功能来实现这一点?
一个相关的问题: 创建一个已完成的任务<T>
你可以使用Task。FromResult(在。net 4.5中)返回一个完成的Task<T>。
如果你需要一个非泛型任务,你总是可以使用Task. fromresult(0)或类似的方法,因为Task<T>是Task的子类。
Task<T>隐式可转换为Task,因此只需获得一个完成的Task<T>(具有任何T和任何值)并使用它。你可以使用类似这样的东西来隐藏实际结果在某处的事实。
private static Task completedTask = Task.FromResult(false);
public static Task CompletedTask()
{
return completedTask;
}
注意,由于我们没有公开结果,并且任务总是完成的,所以我们可以缓存单个任务并重用它。
如果你正在使用。net 4.0并且没有FromResult,那么你可以使用TaskCompletionSource创建自己的FromResult:
public static Task<T> FromResult<T>(T value)
{
var tcs = new TaskCompletionSource<T>();
tcs.SetResult(value);
return tcs.Task;
}
我会使用Task.Delay(0)。在内部,它返回已完成Task<T>的缓存实例。这正是当前的答案所建议的,只是现在您不必自己缓存实例,也没有任何不优雅的垃圾值在您的代码中。
您可能认为可以使用Task. yield()来代替,但事实证明Task. yield()的结果不是Task的子类型,而Task. delay(0)的结果是。这是两者之间的细微差别之一。
最新版本的。net (v4.6)就是增加了一个内置任务。CompletedTask:
Task completedTask = Task.CompletedTask;
该属性被实现为无锁单例,因此您几乎总是在使用相同的已完成任务。
我最喜欢的方法是调用Task.WhenAll(),不带参数。MSDN文档声明“如果提供的数组/枚举对象不包含任务,返回的任务将在返回给调用者之前立即转换到RanToCompletion状态。”听起来是你想要的。
更新:我在微软的参考源代码中找到了源代码;你可以看到这个任务。WhenAll包含以下内容:
return (tasks.Length == 0) ? // take shortcut if there are no tasks upon which to wait
Task.CompletedTask :
new WhenAllPromise(tasks);
所以任务。CompletedTask确实是内部的,但是通过调用不带参数的WhenAll()来公开它。
如何:
#pragma warning disable 1998
public async Task emptyTask() {
}
#pragma warning restore 1998
如果您不介意的话,可以省略警告抑制。
适用于。net 4.6及以上版本
return Task.CompletedTask;
对于低版本,您可以使用
return new Task(() => { });