创build一个完成的任务
我想创build一个完成的Task
(不是Task<T>
)。 是否有内置的.NET来做到这一点?
一个相关的问题: 创build一个完成的任务<T>
.Net(v4.6)的最新版本增加了一个内置的Task.CompletedTask :
Task completedTask = Task.CompletedTask;
该属性是作为一个无锁单身实施,所以你几乎总是会使用相同的完成任务。
Task<T>
可隐式转换为Task
,所以只需获得一个完整的Task<T>
(任何T
和任何值)并使用它。 你可以使用这样的东西来隐藏实际结果在某处的事实。
private static Task completedTask = Task.FromResult(false); public static Task CompletedTask() { return completedTask; }
请注意,由于我们没有公开结果,任务总是完成,所以我们可以caching一个任务并重用它。
如果您使用的是.NET 4.0,并且没有FromResult
那么您可以使用TaskCompletionSource
创build自己的:
public static Task<T> FromResult<T>(T value) { var tcs = new TaskCompletionSource<T>(); tcs.SetResult(value); return tcs.Task; }
我这样做的首选方法是调用Task.WhenAll()
没有参数。 MSDN文档指出:“如果提供的数组/枚举不包含任务,返回的任务会在返回给调用者之前立即转换为RanToCompletion状态。” 这听起来像你想要的。
更新:我在微软的Reference Sourcefind了这个源代码 ; 在那里你可以看到Task.WhenAll包含以下内容:
return (tasks.Length == 0) ? // take shortcut if there are no tasks upon which to wait Task.CompletedTask : new WhenAllPromise(tasks);
所以Task.CompletedTask确实是内部的,但它通过调用没有参数的WhenAll()来公开。
我会使用Task.Delay(0)
。 在内部,它返回一个完成的Task<T>
的caching实例。 这正是现在的答案,无论如何,只有现在你不必自己caching一个实例,也不会在代码中有任何不雅的垃圾值。
你可能会认为你可以使用Task.Yield()
来代替,但是Task.Yield()
的结果不是 Task
的子types,而Task.Delay(0)
的结果是。 这是两者之间的细微差别之一。
您可以使用Task.FromResult (在.NET 4.5中)返回完成的Task<T>
。
如果您需要非通用Task
,则可以始终使用Task.FromResult(0)
或类似的Task<T>
,因为Task<T>
是Task
的子类。
对于.Net 4.6及以上版本使用
return Task.CompletedTask;
对于较低版本,您可以使用
return new Task(() => { });
您可以从Stephen Cleary的一个伟大的库AsyncEx中使用Nito.AsyncEx.TaskConstants.Completed 。
怎么样:
#pragma warning disable 1998 public async Task emptyTask() { } #pragma warning restore 1998
如果你不介意的话,你可以忽略警告抑制。