【问题标题】:C# Task CancellationC# 任务取消
【发布时间】:2021-04-16 08:38:48
【问题描述】:

我正在寻求澄清。我在 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 之后触发。如果没有延迟,则在调用 tokenSource 的 Cancel 方法之前将 show 变量设置为 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);

我的理解是我可以在任何给定时间取消任务?

【问题讨论】:

  • 如果你想取消延迟,你也需要将令牌传递给它。 await Task.Delay(100, tokenSource.Token);
  • Task.Yield 有什么作用,您希望通过使用它实现什么?
  • @Fildor 这不是我的意思。我将澄清我的问题:延迟是必要的,因为HandleFocus 是在HandleBlur 之后触发的。如果没有延迟,则在调用 tokenSource 的 Cancel 方法之前将 show 变量设置为 false。我的问题是关于Task.Delay(100) 的位置。如果我在任务内或 try 块内调用它,它没有任何效果,并且 show = false 被执行,即使 tokenSource.Cancel() 应该停止它
  • 所以,你是说你有时间问题,不是吗?
  • @Fildor 可以归结为这一点。

标签: c# task task-parallel-library blazor


【解决方案1】:

CancellationToken 是一个合作的东西。调用Cancel() 方法不会杀死或中止任何事情。它只是设置令牌的IsCancellationRequested 属性。您必须实现适当的逻辑,以便在任务执行期间定期查询该属性值并根据需要对其进行响应。

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

【讨论】:

    猜你喜欢
    • 2019-01-06
    • 1970-01-01
    • 1970-01-01
    • 2018-09-05
    • 1970-01-01
    • 2016-05-08
    • 1970-01-01
    • 1970-01-01
    • 2019-07-03
    相关资源
    最近更新 更多