0

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

这在一个 Web 服务器中运行良好,但在其他 Web 服务器中表现奇怪。即使堆栈中有项目,线程也会无缘无故地空闲 6-12 秒,并且什么也不做。

  • 在堆栈对象上使用 lock() 使 Push & Pop 线程安全
  • 尝试 Thread.Yield() 让 cpu 让出以执行其他线程,但减慢执行速度和闲置仍然存在
  • 尝试 Thread.Sleep(0) 让 cpu 让出以执行其他线程,但减慢执行速度和闲置仍然存在
  • 记录所有方法的条目和退出,以检查执行过程中是否出现问题,但没有运气

我的问题:

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

2013 年 5 月 8 日更新

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

我们尝试了几次迭代,在所有情况下 webserver1 都可以正常执行,并像之前一样快速完成后台工作。但是 webserver2 有很大的延迟并且性能很差。

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

任何想法 ?

4

2 回答 2

0

您的线程反复尝试获取可能导致争用的锁。但不应该是 6-12 秒 - 只有调试器才能提供的答案。

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

于 2013-05-07T18:10:04.273 回答
0

好的,伙计们,我们终于解决了这个问题。

网络服务器的 CPU 核心之一达到 100% 并且再也没有回来。而其他核心为 0-5%。

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

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

于 2013-06-01T15:58:42.300 回答