C# 创建已完成的任务

C# 创建已完成的任务,c#,.net,async-await,task-parallel-library,C#,.net,Async Await,Task Parallel Library,我想创建一个已完成的任务(不是任务)。NET中是否内置了这样做的功能 一个相关问题: 您可以使用(在.NET 4.5中)返回已完成的任务 如果您需要非通用的任务,您可以始终使用任务。FromResult(0)或类似的,因为任务是任务的子类任务可以隐式转换为任务,所以只需获得一个已完成的任务(带有任意T和任意值)并使用它即可。你可以用这样的方法来隐藏这样一个事实:一个实际的结果就在那里,某个地方 private static Task completedTask = Task.FromResult

我想创建一个已完成的
任务
(不是
任务
)。NET中是否内置了这样做的功能

一个相关问题:

您可以使用(在.NET 4.5中)返回已完成的
任务

如果您需要非通用的
任务
,您可以始终使用
任务。FromResult(0)
或类似的,因为
任务
任务

的子类

任务
可以隐式转换为
任务
,所以只需获得一个已完成的
任务
(带有任意
T
和任意值)并使用它即可。你可以用这样的方法来隐藏这样一个事实:一个实际的结果就在那里,某个地方

private static Task completedTask = Task.FromResult(false);
public static Task CompletedTask()
{
    return completedTask;
}
请注意,由于我们不公开结果,而且任务总是完成的,因此我们可以缓存单个任务并重用它

如果您使用的是.NET 4.0,并且没有
FromResult
,那么您可以使用
TaskCompletionSource
创建自己的源代码:

public static Task<T> FromResult<T>(T value)
{
    var tcs = new TaskCompletionSource<T>();
    tcs.SetResult(value);
    return tcs.Task;
}
公共静态任务FromResult(T值)
{
var tcs=new TaskCompletionSource();
设置结果(值);
返回tcs.Task;
}

我会使用
任务延迟(0)
。在内部,它返回已完成的
任务的缓存实例。这正是当前答案所建议的,只是现在您不必自己缓存实例,代码中也没有任何不雅的垃圾值

您可能认为可以使用
Task.Yield()
,但结果表明
Task.Yield()
不是
Task
的子类型,而
Task.Delay(0)
的结果是。这是两者之间微妙的区别之一。

只是添加了一个内置的:


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

您可以从中的大型库使用。

执行此操作的首选方法是调用无参数的
task.WhenAll()
。状态为“如果提供的数组/枚举表不包含任何任务,则返回的任务将在返回给调用方之前立即转换为RanToCompletion状态。”。听起来像是你想要的

更新:我在上找到了源代码;在那里您可以看到Task.whall包含以下内容:

return (tasks.Length == 0) ? // take shortcut if there are no tasks upon which to wait
            Task.CompletedTask :
            new WhenAllPromise(tasks);
因此Task.CompletedTask确实是内部的,但它是通过调用WhenAll()而公开的,不带任何参数。

#pragma warning disable 1998
    public async Task emptyTask() {
    }
#pragma warning restore 1998

如果您不介意,可以省去警告抑制。

用于.Net 4.6及更高版本

return Task.CompletedTask;
对于较低版本,您可以使用

return new Task(() => { });

我从每个人那里得到的答案似乎是,使用这样的垃圾值是正确的方法。没有垃圾值就没有办法做到这一点令人失望——哦,好吧。
您认为这有什么问题?如果缓存单个
任务
,则整个程序会额外占用一位内存。没什么。而且,一个人可以创建一个完成的任务,而不这样做,这不会更好。哦,我的失望与不得不使用额外的内存无关。只是代码中任何地方的垃圾值都不是优雅的。请注意,现在对于已完成的任务(即,对于您已经拥有的值,以便代码基本上是同步的),都有
ValueTask
,这将为您节省一个分配。如果您使用的是4.0,则可以添加Microsoft.Bcl.Async库以获取TaskEx.FromResult,还有其他方便的东西,比如WhenAll@ServyFromResult(false)和FromResult(true)有什么变化?@FrancescoB。如果您查看结果,则会更改结果的布尔值。如果您忽略了结果,那么结果是无关的。只需检查最新的VS 14 CTP并创建一个4.5.3项目,
Task。CompletedTask
仍然是内部的。2。您没有下载最新的CTP(它是4,并从该站点链接到),或者您没有指定版本4.5.3@PeterRitchie从Azure上的Visual Studio 14映像创建了一个VM。@PeterRitchie我正在使用mono 5.4.1.7的Mac OS X上工作,我收到了相同的错误。我怎样才能修复它呢?虽然它确实感觉有点黑客,但它有来自文档的支持,所以我不知道,我有点喜欢它!对于我和我的.NET4.5.2受约束代码来说,它已经足够优雅了。谢谢指向Nito.AsyncEx.TaskConstants.Completed源文件的链接为dead@harlam357修正。对于4.6之前的方法,小心!你需要开始这项任务,否则它将永远无法完成!如何使用
返回任务。延迟(0)相反?我相信,即使您不使用方法
async
标记方法,仍然会创建整个状态机设备,因此在资源不足的情况下,返回空任务更有效。
return new Task(() => { });