C#:异步任务:取消

C#: Async Task: Cancel

我有一个函数可以在几秒钟内完成一些工作。我试图在一段时间后取消该任务,但我无法这样做。我的 objective 是执行 asyncFunction 5 秒,然后转到另一个任务。出于某种原因,我似乎无法等待 _t1。

private async Task asyncFunction(string line_1, string line_2, string line_3, string line_4, int _time, System.Threading.CancellationTokenSource _cts)
    {
        _cts.Token.ThrowIfCancellationRequested();

        await Task.Run(async () => {
            someFunction_01(line_1, line_2, line_3, line_4);                
            someFunction_01("HELLO WORLD");
            await Task.Delay(_time, _cts.Token);
        });
    }

我调用函数的方式是:

TimeSpan _timeout = TimeSpan.FromSeconds(5);
            var timeoutCancellationTokenSource = new System.Threading.CancellationTokenSource(_timeout);
            
            Task _t1 = asyncFunction("LINE 01", " ", " ", " ", 6000, timeoutCancellationTokenSource);
if (await Task.WhenAny(_t1, Task.Delay(_timeout, timeoutCancellationTokenSource.Token)) == _t1)
            {                    
                await _t1;
            }
            else
            {
                // timeout/cancellation logic                    
                timeoutCancellationTokenSource.Cancel();
            }

我似乎无法取消 asyncFunction 中的 Task.Delay。感谢任何代码帮助。

我不太明白这段代码的用途。特别是 if-statement:

if (await Task.WhenAny(_t1, Task.Delay(_timeout, timeoutCancellationTokenSource.Token)) == _t1)

为什么将 _timeout 传递给 Task.Delay,这与您创建 timeoutCancellationTokenSource 的超时相同?

如果我们忽略您提供的第一个参数 Task.Delay 这也意味着您使用相同的 CancellationToken 两次调用 Task.Delay 现在您有一个 race-condition 其中无法预测哪个 Task.Delay 会先被取消。


要显示如何使取消生效的示例,您可以这样做:

TimeSpan _timeout = TimeSpan.FromSeconds(1);
var timeoutCancellationTokenSource = new System.Threading.CancellationTokenSource(_timeout);

Task _t1 = asyncFunction("LINE 01", " ", " ", " ", 2000, timeoutCancellationTokenSource);
try
{
    await _t1;
}
catch (OperationCanceledException)
{
    Console.WriteLine("Operation was cancelled");
}

// Output: Operation was cancelled

如果 _timeout 比传入 asyncFunction2000 毫秒长,任务将在 2 秒后完成而不会被取消。

请参阅 this fiddle 进行测试 运行。