Cancellationtoken 在取消之前等待整个延迟时间

Cancelation token waits entire delay duration before cancelling

在下面的代码中,如果 UserCancelled 属性 设置为 true,我希望它立即结束循环并继续代码。

我面临的问题是它在 6 秒过去后继续,而不是之前,我认为取消令牌会提前结束延迟。

有哪些选项可以更快地结束这种延迟?

CancellationTokenSource _source = new CancellationTokenSource();
var token = _source.Token;
foreach (var mock in lst)
{
    if (UserCancelled)
    {
       _source.Cancel();
       _source.Dispose();
       break;
    }
    
       label1.Text = mock.Name;
       await Task.Delay(6000, token);
                    
 }
    
 label1.Text += " Broke Out";

如果我们进入循环时UserCancelled已经设置为true,那么您应该立即取消。

如果 UserCancelled 在初始检查时是 false,那么您将前往 Task.Delay 并开始等待。等待期间不执行任何额外检查。

60 秒后工作恢复,然后您继续循环的下一次迭代。同样,如果 f UserCancelled 设置为 true,您将取消并退出,否则将再等待 60 秒。

此处最好的解决方案是使 _source 变量可用于代码,即设置 UserCancelled。而这样的代码会直接调用_source.Cancel()

因为等了6秒后continuation执行完才请求取消。将取消源提取到一个字段中,并在您将 UserCancelled 设置为 true 时调用 _source.Cancel()

label1 提示我这是某种 UI 代码,所以我会像这样重构它:

// this is a field
private CancellationTokenSource _source = new CancellationTokenSource();

// call this from whatever handler/command and pass _source.Token to it:
private async Task DoMyTaskAsync(CancellationToken token)
{
    foreach (var mock in lst)
    {
        if (token.IsCancellationRequested)
            break;
    
       label1.Text = mock.Name;
       await Task.Delay(6000, token);                    
     }
    
     label1.Text += " Broke Out";
}

// can be a simple event handler, too (eg. for some btnCancel.Click)
private void OnCancelCommand()
{
    // avoid double cancellation and ObjectDisposedException
    if (UserCancelled)
        return;
    _source.Cancel();
    _source.Dispose();
    UserCancelled = true;
}