如何取消 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);
}
我知道如何取消任务,但找不到有关如何将取消添加到 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);
}