如何知道线程池中的线程挂起/冻结

时间:2010-12-14 07:46:29

标签: c# multithreading threadpool

我有ThreadPool的任务队列,每个任务都有冻结锁定它正在使用的所有资源的倾向。除非服务重新启动,否则不能发布这些内容。

ThreadPool中有没有办法知道它的线程已被冻结?我有一个使用超时的想法,(虽然我仍然不知道如何写它),但我认为它不安全,因为处理的时间长度不均匀。

3 个答案:

答案 0 :(得分:3)

我不想在这里过于放肆,但实际上找出问题所在并确定问题是最好的解决方案。

  • 运行服务的调试版本并等待其死锁。它会陷入僵局,因为这是一个很好的死锁属性。
  • 将Visual Studio调试器附加到服务。
  • “Break All”。
  • 打开你的线程窗口,开始探索......

除非你有一个健全的架构\设计\理由首先选择受害者,否则不要这样做 - 期间。当它们处于某种状态的中间时,任意地将线程砸在头上是一种灾难。

答案 1 :(得分:2)

(这可能有点低级,但至少它是一个简单的解决方案。由于我不知道C#的API,这是使用线程池的任何语言的通用解决方案。)

在使用当前时间更新时间值的每个实际任务之后插入监视程序任务。如果此值大于最大任务运行时间(例如10秒),则表示存在某些问题。

您可以在未来10秒内连续设置和重置某些计时器,而不是设置时间并进行轮询。当它触发时,任务已挂起。

最好的方法可能是将每个任务包装在一个自动执行此操作的“Watchdog”Task类中。这样,完成后,您将清除计时器,并且还可以设置每任务超时,这可能很有用。

你显然需要一个时间/计时器对象用于线程池中的每个线程,但这可以通过线程局部变量解决。

请注意,此解决方案不需要您修改任务代码。它只修改将任务放入池中的代码。

答案 2 :(得分:1)

一种方法是使用看门狗定时器(通常在硬件中完成但也适用于软件的解决方案)。

让每个线程至少每五秒钟将一个特定于线程的值设置为1(例如)。

然后你的看门狗定时器每十秒唤醒一次(再次,这只是一个示例图)并检查以确保所有值都是1.如果它们 1,那么一个线程已经锁定了。

看门狗定时器然后将它们全部设置为0并在下一个周期返回休眠状态。

提供您的工作线程是以这样的方式编写的,以便他们能够在非冻结条件下及时设置值,此方案可以正常工作。

锁定的第一个线程不会将其值设置为1,这将在下一个周期由看门狗定时器检测到。


然而,更好的解决方案是首先找出线程冻结的原因并修复它。