【问题标题】:Stop Prev Task and Run New Task wpf停止上一个任务并运行新任务 wpf
【发布时间】:2019-06-25 23:57:33
【问题描述】:

如果用户更改了列表框项并且之前的任务尚未完成,我希望该任务停止并启动新任务。我该怎么做?
我使用了这段代码,但没有用。

CancellationTokenSource source = new CancellationTokenSource();
CancellationToken token;
private void Listbox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    if (task != null && (task.IsCompleted == false || task.Status == TaskStatus.Running))
    {
        if (source != null)
            source.Cancel();
    }

    task = LoadArts();
}

private async Task LoadArts()
{
    token = source.Token;
    await Task.Run(() =>
    {
    }

    , token);
}

【问题讨论】:

  • 取消不只是发生。您需要在您正在运行的任务中执行代码操作。您尚未向我们展示您的代码,但请参阅 docs.microsoft.com/en-us/dotnet/standard/parallel-programming/…docs.microsoft.com/en-us/dotnet/standard/parallel-programming/… 从后者“通知并响应您的用户委托中的取消请求”。简单地忽略从任务返回的内容(无论如何都在另一个线程上)而不是尝试取消它会更方便。
  • 与其取消当前任务(可能很难实现)考虑使用队列。在最简单的形式中,您可以使用ContinueWith(参见TaskQueue)。您可以将LoadArts 拆分为两个不同的部分:加载数据并显示它们,在每个部分之前您可以检查队列是否为空,如果不是则退出任务。 ContinueWith 会注意运行下一个任务(如果队列仍然不为空,它们都会立即退出),直到最后一个项目,然后能够通过显示检查,您最终会看到显示的内容。

标签: c# wpf asynchronous async-await task


【解决方案1】:
  1. 您应该将CancellationToken 传递给在任务中运行的代码,并不时调用令牌上的ThrowIfCancellationRequested 方法。
  2. 您应该在委托之后将取消令牌传递给Task.Run 方法。由于取消是通过抛出OperationCanceledExceptionTaskCanceledException 来完成的,因此任务的状态将变为错误,因为其中抛出了异常。当您传递令牌时,任务会将其与取消异常中的令牌进行比较,如果它们匹配,则任务将被取消,而不是出错。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-06-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-21
    • 1970-01-01
    相关资源
    最近更新 更多