为什么要使用Task< T>超过ValueTask< T>在C#中? [英] Why would one use Task<T> over ValueTask<T> in C#?

查看:149
本文介绍了为什么要使用Task< T>超过ValueTask< T>在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 a Task<TResult>. For example, while a ValueTask<TResult> can help avoid an allocation in the case where the successful result is available synchronously, it also contains two fields whereas a Task<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 an async method, the state machine for that async 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 a Task<TResult> with a cached task as a common result or a ValueTask<TResult>. If the consumer of the result wants to use it as a Task<TResult>, such as to use with in methods like Task.WhenAll and Task.WhenAny, the ValueTask<TResult> would first need to be converted into a Task<TResult> using AsTask, which leads to an allocation that would have been avoided if a cached Task<TResult> had been used in the first place.

As such, the default choice for any asynchronous method should be to return a Task or Task<TResult>. Only if performance analysis proves it worthwhile should a ValueTask<TResult> be used instead of Task<TResult>.

这篇关于为什么要使用Task&lt; T&gt;超过ValueTask&lt; T&gt;在C#中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆