将 ValueTask<T> 转换为非泛型 ValueTask

Spi*_*Spi 5 .net c# async-await valuetask

这里提出的问题与这里的问题相同,旨在为其创建一个明确的解决方案。最准确的答案是 Stephen Toub 本人在本期中提出的,正是关于这个问题的。“推荐代码”如下:

public static ValueTask AsValueTask<T>(this ValueTask<T> valueTask)
{
    if (valueTask.IsCompletedSuccessfully)
    {
        valueTask.GetResult();
        return default;
    }

    return new ValueTask(valueTask.AsTask());
}
Run Code Online (Sandbox Code Playgroud)

这个答案不是最新的 - ValueTask 不公开 GetResult() (只有 Result 属性) - 问题是:

  • 我们是否需要将Result从ValueTask中“拉”出来(以“释放”这个ValueTask下可能操作的IValueTaskSource)?
  • 如果是:
    • .GetAwaiter()上面缺少的调用吗?
    • 或者对物业的假电话是否保证有效var fake = valueTask.Result;?总是?(我担心死代码消除。)
  • 如果不是,像下面这样的直接实现是否足够(并且是最佳的)?
public static ValueTask AsNonGenericValueTask<T>( in this ValueTask<T> valueTask )
{
    return valueTask.IsCompletedSuccessfully ? default : new ValueTask( valueTask.AsTask() );
}
Run Code Online (Sandbox Code Playgroud)

Pau*_*ado 2

该代码中缺少的是.GetAwaiter()

public static ValueTask AsValueTask<T>(this ValueTask<T> valueTask)
{
    if (valueTask.IsCompletedSuccessfully)
    {
        valueTask.GetAwaiter().GetResult();
        return default;
    }

    return new ValueTask(valueTask.AsTask());
}
Run Code Online (Sandbox Code Playgroud)

你是部分正确的,因为你不关心结果。但是您可能会关心抛出的异常或取消,如果您不查询结果,您就会错过这些异常或取消。

或者你可以这样写:

public static async ValueTask AsValueTask<T>(this ValueTask<T> valueTask)
    => await valueTask;
Run Code Online (Sandbox Code Playgroud)