gpt4 book ai didi

c# - 我应该在调用异步方法的方法中返回 ValueTask 还是 Task

转载 作者:行者123 更新时间:2023-12-04 03:24:41 24 4
gpt4 key购买 nike

我有一个具有以下签名的方法:

public async Task<Result> CreateAsync(T entity)
{
try
{
await _c.CreateItemAsync(entity);

return Result.Ok();
}
catch (Exception e)
{
return Handle(e); // returns a `Result`
}
}
_c 是 CosmosDB 的 Container
现在,我有另一种方法:
public Task<Result> CreateUserAsync(User user)
{
var userEntity = new UserEntity { Id = user.Id, Name = user.Name };
return CreateAsync(userEntity);
}
Result.Ok() 是自定义类 Result 的一个非常简单的静态方法:
class Result
{
public static Result Ok() { return new Result(); }.
}
所以,我有两种方法,一种是 Task<Result> CreateUserAsync(User user) ,它返回一个简单的 Task ,不等待其中的任何内容,但我在最后调用的另一个任务 return CreateAsync(userEntity); 等待其中的内容。
因此,据我所知, CreateAsync() 应该保留为 Task 返回类型,因为它在其中执行异步内容,但是我从中调用它的方法(即 CreateUserAsync() )是否也需要保留 Task ,还是可以成为 ValueTask

最佳答案

它们在功能上相似,但有一些重要的区别:

  • 如果作业立即(同步)完成,Task<T> 需要每次分配(除了一些关于 bool 值和小整数的琐碎情况),其中 ValueTask<T> 可以避免这种情况下的分配
  • 在真正异步的情况下,ValueTask<T> 有可能摊销分配,尽管这需要特殊代码(IValueTaskSource<T> 等)
  • 可以多次等待 Task<T>,其中,ValueTask<T> 只应等待一次(等待多次时行为未定义,作为上述“2”的副作用)

  • 如果这是一个高吞吐量的代码路径,考虑机制的分配开销可能是有用/必要的,在这种情况下 ValueTask<T> 开始变得非常诱人 - 但是,如果预先存在的代码可能已经 await 结果不止一次(违反第三点),这可能有问题。如果异步机制的开销很大(在您的场景中进行测量之后),则第 1 点和第 2 点可能会产生重大影响。
    如果这是一个低吞吐量的代码路径,老实说:做任何你想做的事。 Task<T> 的优点是甚至不需要考虑第三个要点,这使得它很有吸引力。

    关于c# - 我应该在调用异步方法的方法中返回 ValueTask 还是 Task,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67803280/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com