为什么C#线程在执行期间空闲?

时间:2013-05-07 17:32:08

标签: c# .net multithreading parallel-processing clr

我有一个调度程序,它在ASP.NET站点的应用程序启动时作为后台线程运行。用户可以启动插入db表中的各种任务(警报电子邮件/文件生成等)。调度程序将从数据库中选择任务并将项目推入堆栈。调度程序还有一个运行10个后台线程的线程池,它将从堆栈中弹出任务项并执行它。

这在一台Web服务器上正常运行,但在其他Web服务器中表现得很奇怪。线程无缘无故地空闲6-12秒,即使堆栈中有项目也不执行任何操作。

  • 在堆栈对象上使用lock()来生成Push&弹出线程安全
  • 尝试使用Thread.Yield()为cpu提供执行其他线程,但减慢执行速度并继续空闲仍然存在
  • 试过Thread.Sleep(0)给cpu执行其他线程,但减慢执行速度并且空闲仍然存在
  • 记录条目并退出所有方法,以检查执行过程中是否出错,但没有运气

我的问题:

  1. 执行.net中的线程是否具有确定性?
  2. 是否需要指定Thread.Yield()或Thread.Sleep(0)来为cpu提供喘息时间?
  3. 为什么在具有相同配置的盒子上表现不同?是否存在影响线程执行的任何机器/环境特定因素?
  4.   

    2013年5月8日更新

    服务器场中有两个框,两者在硬件配置上相同,设置与Windows 2008 64bit / IIS7相同的软件配置。两个webserver只有一个站点,每个站点具有相同的构建。这两个站点的应用程序池在集成模式下在Framework V4.0上运行。这是遗留代码,自从过去两年以来没有机会。

    我们尝试了几次迭代,在所有情况下,webserver1都会毫无问题地执行,并像之前一样快速完成后台工作。 但是,webserver2有明显的延迟并且表现非常糟糕。

    我们尝试了大量的日志记录,捕获所有方法的条目/退出。场景是这样的,所有线程工作正常2秒然后空闲6-12秒,再次变为活动并执行接下来的2秒然后再次空闲。在完成任务之前,这种行为是一致的。没有异常,没有应用程序终止,应用程序池/ iis日志中没有错误。

    有什么想法吗?

2 个答案:

答案 0 :(得分:0)

你的线程一再试图抓住一个可能导致争用的锁。但不应该是6-12秒 - 只有调试者可以提供答案。

您可以使用AutoResetEvent并在工作线程中等待它 - 以及当您将项目推送到堆栈时Set该事件。

答案 1 :(得分:0)

好的,最后我们把这个问题固定下来了。

网络服务器的一个cpu核心达到100%并且永远不会回来。而其他核心为0-5%。

我们对正常 - 中等 - 重载荷进行了负载测试。在生成正常到中等负载的同时,服务器正在提供良好的服务,正确地与所有其他cpu核心共享流程执行。但是当我们产生大量负载时,事情会发生变化,服务器难以在内核之间分配负载,并且线程会空闲6-7秒。我们假设由于一个cpu核心的故障,它处理一些模糊逻辑以在核心之间分配进程。

经过进一步调查,我们发现Windows NT内核导致此问题,可能是由于损坏或驱动程序相关问题。