C# 任务取消

C# Task Cancellation

我正在寻求澄清。我在 Blazor 服务器端应用程序中。基本上,当用户在下拉列表中的输入字段内单击时,我正在处理一个下拉列表保持打开状态的事件。 我有以下代码:

private async Task HandleBlur(FocusEventArgs a)
{
    tokenSource = new CancellationTokenSource();
    await Task.Delay(100);
    var task = Task.Run(() =>
    {
        show = false;
        InvokeAsync(StateHasChanged);
    }, tokenSource.Token);
    await Task.Yield();
    try
    {
        await task;
    }
    catch (AggregateException e)
    {

    }
}

private void HandleFocus(FocusEventArgs a)
{
    tokenSource?.Cancel();
}

public void Dispose()
{
    tokenSource.Dispose();
}

延迟是必要的,因为 HandleFocus 在 HandleBlur 之后触发。如果没有延迟,show 变量将在调用 tokenSource 的 Cancel 方法之前设置为 false。我的问题是关于 Task.Delay(100) 的位置。如果我在任务内或 try 块内调用它,它不会有任何效果并执行 show = false,即使 tokenSource.Cancel() 应该已停止它。

以下无效

    try
    {
        await Task.Delay(100);
        await task;
    }

或在任务本身中

    var task = Task.Run(() =>
    {
        await Task.Delay(100);
        show = false;
        InvokeAsync(StateHasChanged);
    }, tokenSource.Token);

我的理解是我可以随时取消任务?

CancellationToken是合作的事情。调用 Cancel() 方法不会终止或中止任何操作。它只是设置令牌的 IsCancellationRequested 属性。您必须实施适当的逻辑以在任务执行期间定期查询该 属性 值并根据需要响应它。

内置方法实现了协作代码。例如。如果你想让它被取消,你应该调用 Task.Delay(100, token) 而不是 Task.Delay(100)