Axa*_*kat 9 c# task-parallel-library azure-cosmosdb
我有一个具有以下签名的方法:
public async Task<Result> CreateAsync(T entity)
{
try
{
await _c.CreateItemAsync(entity);
return Result.Ok();
}
catch (Exception e)
{
return Handle(e); // returns a `Result`
}
}
Run Code Online (Sandbox Code Playgroud)
_c 是ContainerCosmosDB 的。
现在,我有另一种方法是这样的:
public Task<Result> CreateUserAsync(User user)
{
var userEntity = new UserEntity { Id = user.Id, Name = user.Name };
return CreateAsync(userEntity);
}
Run Code Online (Sandbox Code Playgroud)
Result.Ok()是自定义类的一个非常简单的静态方法Result:
class Result
{
public static Result Ok() { return new Result(); }.
}
Run Code Online (Sandbox Code Playgroud)
因此,我有两种方法,一种是Task<Result> CreateUserAsync(User user),它返回一个简单的Task,而不等待其中的任何内容,但我最后调用的另一个任务return CreateAsync(userEntity);等待其中的内容。
因此,根据我的理解,CreateAsync()应该保留为Task返回类型,因为它在其中执行异步操作,但是我调用它的方法(即CreateUserAsync())也需要保留Task,还是可以成为ValueTask?
Mar*_*ell 15
它们在功能上相似,但有一些重要的区别:
Task<T>每次都需要分配(除了一些关于布尔值和小整数的琐碎情况),其中 -as aValueTask<T>可以避免这种情况下的分配ValueTask<T> 有可能摊销分配,尽管这需要特殊代码(IValueTaskSource<T>等)Task<T>可以等待多次,而 aValueTask<T>只能等待一次(当等待多次时,行为是未定义的,作为上面“2”的副作用)如果这是一个高吞吐量的代码路径,那么考虑机制的分配开销可能是有用/必要的,在这种情况下ValueTask<T>开始变得非常诱人 - 但是,如果预先存在的代码可能已经await产生多次(违反第三个要点),这可能会出现问题。如果异步机制是一个很大的开销(在您的场景中进行测量之后),第一个和第二个要点可能会产生重大影响。
如果这是一个低吞吐量的代码路径,老实说:做任何你想做的事。Task<T>其优点是甚至不需要考虑第三个要点,这使其很有吸引力。