我要创建一个完成的Task
(不是Task<T>
)。.NET是否有内置的工具可以做到这一点?
一个相关的问题: 创建完成的Task <T>
ValueTask
完成的任务(例如,您已经拥有的值,因此代码本质上是同步的),这将节省您的分配。
我要创建一个完成的Task
(不是Task<T>
)。.NET是否有内置的工具可以做到这一点?
一个相关的问题: 创建完成的Task <T>
ValueTask
完成的任务(例如,您已经拥有的值,因此代码本质上是同步的),这将节省您的分配。
Answers:
.Net(v4.6)的最新版本仅添加了一个内置Task.CompletedTask:
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;
}
注意,由于我们不公开结果,并且任务总是完成的,因此我们可以缓存单个任务并重用它。
如果您使用的是.NET 4.0,FromResult
则可以使用TaskCompletionSource
以下方法创建自己的:
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.CompletedTask确实是内部的,但是通过不带任何参数的whenAll()公开它。
您可以使用Task.FromResult(在.NET 4.5中)返回completed Task<T>
。
如果您需要非泛型Task
,则可以始终使用Task.FromResult(0)
或类似Task<T>
的类,因为它是的子类Task
。
It seems like the answer I'm getting from everyone is that using a garbage value like this is the correct way. That there isn't a way to do this without the garbage value is disappointing -- oh well.
您认为这有什么问题?如果仅缓存一个,Task
则整个程序将占用额外的一小部分内存。那是什么。同样,如果不这样做就可以创建完成的任务,这将再好不过了。