【问题标题】:Race condition when cancelling tasks during app deactivation在应用停用期间取消任务时的竞争条件
【发布时间】:2013-02-12 20:07:56
【问题描述】:

我正在尝试在我的 Windows Phone 8 应用程序中使用基于任务的异步模式。想法是所有长时间运行的操作都引用取消令牌,并且在应用程序中有一个存储所有这些令牌的地方。当应用收到Deactivated 事件时,它会遍历所有令牌并取消它们。

问题是长时间运行的线程没有安排在应用程序停用时运行,这意味着如果我试图在该线程中使用CancellationToken.ThrowIfCancellationRequested();,它只会在应用程序恢复时调用,而不是在应用程序恢复时调用停用。当然,这不是我想要的。如果我正在做一个像token.Register(() => Thread.Sleep(1000)); 这样的简单技巧,即暂停调用取消的线程片刻,那么第二个线程就有机会运行,并且一切都像魅力一样被取消。但是,这是一个肮脏的 hack,我不想在我的应用程序中使用它。

问题是如何确保在操作取消完成时应用程序没有退出?我假设合作取消的标志是抛出 OperationCancelledException,但是如何等待它,特别是如果我只有对 CancellationTokenSource 的引用,而不是对 Task 对象的引用?有其他方法可以知道吗?

提前非常感谢!

附:如果您需要更多代码来帮助我,尽管问。

【问题讨论】:

  • 为什么这不是你想要的?为什么只有在应用程序恢复后实际取消操作才重要?
  • 我的工作线程没有收到关于取消的通知,这就是问题所在。它应该停止写入文件并在取消请求时正确关闭它,然后抛出 OperationCancelledException 作为成功取消的确认。如果在应用停用之前不会发生这种情况,则文件可能会处于某种意外状态,因为应用可能会在停用后被杀死。

标签: c# exception windows-phone-8 async-await lifetime


【解决方案1】:

我认为在您的情况下存储所有CancellationTokens 还不够,您还需要存储相应的Tasks。在您的Deactivated 处理程序中,您将取消所有令牌,然后取消await 所有存储的Tasks(捕获OperationCancelledExceptions)。 (我不确定Deactivatedasync 到底是如何工作的,你可能需要一些东西让系统知道你实际上还没有完成停用。)

【讨论】:

  • 谢谢,我已经尝试过了,我认为它应该可以工作。但是,我在执行方面遇到了问题。您认为向这个问题添加细节或创建一个单独的问题有意义吗?
猜你喜欢
  • 1970-01-01
  • 2016-11-16
  • 1970-01-01
  • 2016-12-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-14
相关资源
最近更新 更多