【问题标题】:Non-cooperative cancellation of an asynchronous operation异步操作的非合作取消
【发布时间】:2012-03-12 13:04:20
【问题描述】:

在我的 Windows 窗体应用程序中,我需要调用第三方数学库 (Accord.NET) 的长时间运行操作。在计算过程中,我想让我的 GUI 保持响应,并让用户可以取消长时间运行的操作。

有没有办法在后台线程中执行该功能并让用户可以取消它?请注意,我想调用的长时间运行的函数位于外部库中,并且不接受CancellationToken(否则我可以轻松使用ThreadPoolQueueUserWorkItem,例如)。所以我正在寻找一种非合作取消操作的方法。

【问题讨论】:

  • 为什么不使用托管线程?
  • 唯一安全的方法是在单独的 AppDomain 中运行该代码。
  • @HenkHolterman:你有如何在单独的 AppDomain 中执行函数的示例吗?而且我想创建和销毁一个新的 AppDomain 会涉及相当多的开销?

标签: c# multithreading asynchronous


【解决方案1】:

我会说你有三个选择。

第一,将计算旋转到它自己的线程中。这将使 UI 保持响应。而不是取消按钮,只需让用户知道将要执行的操作一旦被盯着就无法停止。

二,像上面一样将计算旋转到它自己的线程中;但是,假装通过简单地降低线程优先级来取消它。您可以让计算继续进行,但只需停止在主线程中报告进度。完成后丢弃结果。

三、把计算放到它自己的appdomain/process中。如果需要,终止该外部进程。


每个人都有好有坏。

【讨论】:

  • +1 建议使线程成为孤儿,饿死它,让它孤独地死去,被忽视,没有人哀悼它,没有悼词,没有墓志铭(呜咽......)
  • @MartinJames: ;) 在这样的情况下会想起一些古老的 Mötley Crüe 歌词:不要生气,走开……
【解决方案2】:

嗯?只需使用 Thread 和 worker 方法。

Thread thread = new Thread(MyWorkerMethod);
thread.Start();

thread.Abort();


void MyWorkerMethod() {
    // do anything you want in here
}

【讨论】:

  • 如果他使用了一个受保护的代码块(例如一个catch-block)。在任何其他情况下都不应该有问题。还是我错过了什么?
  • 看来我错过了最明显的解决方案... :) 感谢@ChrisB 指出这一点。
  • @HenkHolterman:如果我正确理解了Thread.Abort 的文档,只要我的工作函数不持有任何锁并且不调用任何静态构造函数和只要我使用 .Net 2.0 或更高版本。我很确定我要调用的算法不需要任何锁。但是我不太确定静态构造函数...
  • 如果您正在中止的线程正在运行 OP 提到的第 3 方代码,那么您是否中止它有什么关系?我读过的所有反对 Thread.Abort() 的文章都在批评将其用作设计的一部分,而不是与 3rd 方代码有关。即使Peter Ritchie's article cmets “如果这不是你的代码,那么(即它是你无法控制的代码)是的,你别无选择”
  • 第 3 方代码是一个完整的黑洞并不常见。通常,它调用、打开、读取、执行一些可以发出信号以引发某种异常的事情。这似乎是一个数学库,因此您也许可以将它传递的所有数据设置为零并等待出现异常。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-11-14
  • 1970-01-01
  • 2023-03-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多