【问题标题】:How to add cancellation support to async UI tasks?如何为异步 UI 任务添加取消支持?
【发布时间】:2012-09-11 19:25:53
【问题描述】:

我正在考虑为 AsyncUIWinRT XAML Toolkit 库中的等待扩展方法添加取消支持。似乎基本 Task 类没有内置的 Cancel() 方法或事件,并且依赖于我的任务需要定期检查的取消令牌。我认为在我的 UI 场景中没有意义,因为我的任务是使用 TaskCompletionSource 生成的,我想取消 UI 线程上的任务以响应事件,而不是在线程池线程上运行循环并检查令牌.

当 UI 事件发生时,我的任务当前完成 - 例如故事板完成或单击按钮,所以如果我想支持取消 - 我需要通过取消订阅事件和执行其他清理(如停止)来响应取消请求动画。

我正在考虑创建某种 CancellableUITask 基类,而不是使用 TaskCompletionSource,因此我可以公开我的任务使用者可以调用的 Cancel() 方法(例如,停止等待的动画以响应按钮单击) 和类似于虚拟 OnCancellationRequested() 方法的东西,我的情节提要等待任务可以覆盖它以执行清理。

这有意义吗?完成我在此处描述的内容的最佳方法是什么?

【问题讨论】:

  • 我不明白。您的解决方案比使用CancellationToken(可能使用Register() 以避免轮询)和TaskCompletionSource.SetCanceled() 更好吗?
  • 好吧,我不知道注册方法,这就是我问的原因。 :)

标签: wpf silverlight task-parallel-library winrt-xaml async-await


【解决方案1】:

您的任务不需要定期检查是否取消 - 这只是最常见的做事方式。如果您的任务是事件驱动的,那么您可以针对 CancellationToken 注册一个处理程序,该处理程序将在取消时调用。见CancellationToken.Register

所以你的代码可能看起来像这样:

public Task DoSomethingAsync(CancellationToken cancellationToken = default(CancellationToken))
{
    var tcs = new TaskCompletionSource();

    if (cancellationToken.CanBeCanceled)
    {
        // register for notification of cancellation
        cancellationToken.Register(...);
    }

    // set up other handlers and what-not

    return tcs.Task;
}

【讨论】:

  • 我会看看这是否有效。我不太高兴需要为我的所有方法添加另一个重载,使它们看起来更复杂一些。我在想子类化 Task 可以更好地工作。您认为出于某种原因这可能是个坏主意吗?
  • @Filip:需要什么额外的重载?请注意,我为CancellationToken 使用了一个可选参数,因此不需要额外的重载。
  • 我以为一个可选参数会在后面产生一个新的重载?无论如何,我只是查看了我的方法,它们在参数方面并不太复杂,所以另一个 CancellationToken 应该没问题。
  • @FilipSkakun 不,可选参数不会生成新的重载,如果未提供,它总是使用默认值调用原始方法。它可能看起来相同,但在程序集之间调用方法的情况下有点不同。阅读有关默认值的更多信息。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多