为什么要使用Task< T>超过ValueTask< T>在C#中? [英] Why would one use Task<T> over ValueTask<T> in C#?
问题描述
从C#7.0开始,异步方法可以返回ValueTask< T>.解释说,当我们有一个缓存的结果或通过同步代码模拟异步时,应该使用它.但是,我仍然不明白始终使用ValueTask是什么问题,或者实际上为什么从一开始就没有使用值类型来构建async/await. ValueTask何时会无法完成这项工作?
来自 解决方案
From the API docs (emphasis added):
Methods may return an instance of this value type when it's likely that the result of their operations will be available synchronously and when the method is expected to be invoked so frequently that the cost of allocating a new
Task<TResult>
for each call will be prohibitive.There are tradeoffs to using a
ValueTask<TResult>
instead of aTask<TResult>
. For example, while aValueTask<TResult>
can help avoid an allocation in the case where the successful result is available synchronously, it also contains two fields whereas aTask<TResult>
as a reference type is a single field. This means that a method call ends up returning two fields worth of data instead of one, which is more data to copy. It also means that if a method that returns one of these is awaited within anasync
method, the state machine for thatasync
method will be larger due to needing to store the struct that's two fields instead of a single reference.Further, for uses other than consuming the result of an asynchronous operation via
await
,ValueTask<TResult>
can lead to a more convoluted programming model, which can in turn actually lead to more allocations. For example, consider a method that could return either aTask<TResult>
with a cached task as a common result or aValueTask<TResult>
. If the consumer of the result wants to use it as aTask<TResult>
, such as to use with in methods likeTask.WhenAll
andTask.WhenAny
, theValueTask<TResult>
would first need to be converted into aTask<TResult>
usingAsTask
, which leads to an allocation that would have been avoided if a cachedTask<TResult>
had been used in the first place.As such, the default choice for any asynchronous method should be to return a
Task
orTask<TResult>
. Only if performance analysis proves it worthwhile should aValueTask<TResult>
be used instead ofTask<TResult>
.
这篇关于为什么要使用Task< T>超过ValueTask< T>在C#中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!