如何取消 ValueTask<T>

How to cancel ValueTask<T>

我知道如何取消任务,但找不到有关如何将取消添加到 ValueTask 方法的任何信息。 通常我会这样取消任务:

public async Task<int> Foo(
    CancellationToken cancellationToken)
{
    TaskCompletionSource<int> tcsCancel =
        new TaskCompletionSource<int>();

    cancellationToken.Register(() =>
    {
        tcsCancel.TrySetCanceled();
    });

    Task<int> task = LongOperation();

    var completedTask = await Task.WhenAny(
        tcsCancel.Task,
        task).ConfigureAwait(false);

    return await completedTask.ConfigureAwait(false);
}

或者像这样:

if (cancellationToken.IsCancellationRequested)
    return Task.FromCanceled<int>(cancellationToken);

问题是,ValueTask 既没有 FromCanceled 也没有 WhenAny。我应该做...

cancellationToken.ThrowIfCancellationRequested();

您所说的 "cancellation" 并不是真正的取消;您正在取消等待,而不是操作

您可以使用 ValueTask<T> 进行相同类型的假取消;您只需将其转换为 Task<T> 即可:

public async ValueTask<int> Foo(CancellationToken cancellationToken)
{
  using var tcsCancel = new TaskCompletionSource<int>();
  using var registration = cancellationToken.Register(() =>
  {
    tcsCancel.TrySetCanceled();
  });

  ValueTask<int> valueTask = LongOperation();
  Task<int> task = valueTask.AsTask();
  var completedTask = await Task.WhenAny(
      tcsCancel.Task,
      task).ConfigureAwait(false);

  return await completedTask.ConfigureAwait(false);
}