如何在应用程序关闭时停止正在等待Monitor.Wait的LongRunning任务?

时间:2014-01-28 15:18:57

标签: c# task-parallel-library

我有一个长时间运行的Task,它在Monitor.Wait上内部阻塞而没有超时。我的类有一个Dispose方法,允许它解除阻塞,然后等待该任务完成。但是,在某些用法中,我的客户端根本不会调用Dispose,这会导致Task永远被阻止。 这会是一个问题吗? 当客户端应用程序关闭时,如何发出该任务的信号? 我正在考虑使用Finalize方法,但它似乎容易出错。

编辑: 我发现了一篇很好的文章,在几页内解释了很多这样的事情: http://www.albahari.info/threading/threading.pdf

2 个答案:

答案 0 :(得分:4)

你滥用Dispose()进入了这个泡菜。客户端代码在关闭时不太可能使用它,在终结器运行一毫秒后,提前处理非托管资源毫无意义。

但这不是问题。长时间运行的任务使用将IsBackground property设置为true的线程。保存你的培根,CLR将在关闭时自动终止该线程。没有被阻止的任务可以阻止程序正常结束的情况。

答案 1 :(得分:0)

您需要在Monitor.PulseAll(Object)持有时使用该对象的实例执行Monitor.Wait(Object)

来自MSDN:

  

<强> Monitor.PulseAll

     

通知所有等待线程对象状态发生变化。

解决方案

  • 确保您仔细管理使用Monitor方法
  • 的对象的生命周期
  • Thread.Abort。绝对可怕的想法,但毫无疑问有人会提到它。它可以完成任务,可能会让事情变得一团糟。
  • 在致电Monitor.Wait之前,请在object参数中注册一个静态字段,您可以在任何时间段将其用于PulseAll。我不能推荐这个好的设计,但它是一个很好的绑带修复。