6

情况就是这样,我正在编写代码战竞赛的框架。随着代码的运行,对于每一轮,它都会调用每个参赛者提供的库中的一个方法。比赛的规则是方法必须在 1 秒内返回,否则我们会杀死调用它们的任务。然后,我们对该回合使用默认结果。

该方法不支持取消,因为我们不能相信被调用的代码会响应取消。而且我们需要终止线程,因为如果我们有 10 或 20 个被忽略的后台任务,那么所有向前的调用将为每次调用提供更少的时钟周期,而以前花费不到 1 秒的方法现在需要更多。

从好的方面来说,我们正在杀死的方法应该没有打开任何资源等,因此中止不应该留下任何悬而未决的东西。

更新:这里要记住两件事。首先,这就像一场游戏——所以性能很重要。其次,工作线程不太可能打开任何资源。如果调用的方法之一过长,我需要中止它并快速继续。

4

3 回答 3

2

您应该以低权限在自己的 AppDomain 中运行每个参赛者。这有几个优点:

  1. 它是沙盒的
  2. 它不能与进程中的任何其他代码交互
  3. 强制卸载 AppDomain 相对干净。

即使您更喜欢杀死线程而不是卸载 AppDomain,我仍然会将每个参赛者放入 AppDomain 以获得隔离。

不幸Thread.Abort的是还不够。它仍然执行finally可以花费任意时间的子句。

于 2011-08-13T23:08:57.340 回答
1

我建议您在第二个进程中运行代码,并仔细定义与它通信的接口,以确保它可以处理不接收响应的情况。大多数操作系统的设计目的是在杀死进程后进行相当好的清理。

对于通信,您可能应该避免使用 .NET 远程处理,因为这可能会在服务器端处于不一致的状态。其他一些选择:套接字、命名管道、Web 服务。

于 2011-08-13T20:47:49.910 回答
1

Thread.Interrupt() 方法可能是您正在寻找的。

正如 MSDN 文档所说,“如果此线程当前未在等待、睡眠或加入状态下被阻塞,那么它将在下一次开始阻塞时被中断。”

它不是中止,它强制正在运行的线程在线程进入等待状态时抛出 ThreadInterruptedException。

然后,您可以在另一个线程中使用具有超时的计时器来检查线程是否真的不想终止,如果线程拒绝在例如 30 秒内终止,您可以中止它。

于 2011-08-13T20:53:36.970 回答