创建已完成的任务
本文关键字:任务 已完成 创建 | 更新日期: 2023-09-27 17:51:05
我想创建一个完整的Task
(不是Task<T>
(。.NET 中是否内置了一些东西来执行此操作?
一个相关的问题:创建已完成的任务
.Net(v4.6(正在添加内置的Task.CompleteTask:
Task completedTask = Task.CompletedTask;
该属性作为无锁单例实现,因此您几乎总是使用相同的已完成任务。
Task<T>
可以隐式转换为Task
,所以只需获取一个完整的Task<T>
(具有任何T
和任何值(并使用它。 您可以使用这样的东西来隐藏实际结果在某处的事实。
private static Task completedTask = Task.FromResult(false);
public static Task CompletedTask()
{
return completedTask;
}
请注意,由于我们不公开结果,并且任务始终完成,因此我们可以缓存单个任务并重用它。
如果您使用的是 .NET 4.0并且没有FromResult
则可以使用 TaskCompletionSource
创建自己的 .NET 4.0:
public static Task<T> FromResult<T>(T value)
{
var tcs = new TaskCompletionSource<T>();
tcs.SetResult(value);
return tcs.Task;
}
我的首选方法是调用不带参数的Task.WhenAll()
。MSDN 文档指出"如果提供的数组/枚举不包含任何任务,则返回的任务将立即转换为 RanToCompletion 状态,然后再返回到调用方。这听起来像你想要的。
更新:我在Microsoft的参考源中找到了源代码;在那里您可以看到Task.WhenAll包含以下内容:
return (tasks.Length == 0) ? // take shortcut if there are no tasks upon which to wait
Task.CompletedTask :
new WhenAllPromise(tasks);
所以 Task.CompleteTask 确实是内部的,但它是通过调用没有参数的 WhenAll(( 来公开的。
我会使用Task.Delay(0)
.在内部,它返回已完成Task<T>
的缓存实例。这正是当前答案建议做的,只是现在您不必自己缓存实例,也不必在代码中有任何不优雅的垃圾值。
您可能认为您可以使用Task.Yield()
,但事实证明Task.Yield()
的结果不是Task
的子类型,而Task.Delay(0)
的结果是。这是两者之间的微妙区别之一。
Task.FromResult(在 .NET 4.5 中(返回已完成的Task<T>
。
如果您需要非泛型Task
,则始终可以使用Task.FromResult(0)
或类似名称,因为Task<T>
是Task
的子类。
对于 .Net 4.6 及更高版本
return Task.CompletedTask;
对于较低版本,您可以使用
return new Task(() => { });
您可以使用 Nito.AsyncEx.TaskConstants.Complete,来自 Stephen Cleary 的伟大库 AsyncEx。
怎么样:
#pragma warning disable 1998
public async Task emptyTask() {
}
#pragma warning restore 1998
如果您不介意,可以省略警告抑制。