创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 

如果你不介意的话,你可以忽略警告抑制。