【问题标题】:Determine number of threads waiting in threadpool in C#在 C# 中确定线程池中等待的线程数
【发布时间】:2022-01-03 18:47:10
【问题描述】:

是否可以查看线程池的队列中有多少线程正在等待执行?

如果我这样做:

for (int i = 0; i < 5000; i++)
{
    tasks.Add(Task.Run(() => { TaskTest(); }));
}
Task.WaitAll(tasks.ToArray());

在 TaskTest 中,我做了一些通常需要大约 500 毫秒的工作,我还更新了一个具有最高线程数的变量:

ThreadPool.GetMaxThreads(out maxthreads, out completionthreads);
ThreadPool.GetAvailableThreads(out availablethreads, out completionthreads);

int threads_in_use = maxthreads - availablethreads;
mHighwaterThreads = Math.Max(mHighwaterThreads, threads_in_use);

我的电脑的最大线程数通常在 32000 以上。mHighwaterThreads 通常在 75 左右。

我想知道是否有办法查看线程池中有多少线程正在等待执行。

【问题讨论】:

  • 你的意思是线程池中有多少任务正在等待运行
  • 如果你需要知道那你就错了。
  • @Hans,我有一个服务器,每个传入的请求都会创建一个任务。其中一些任务会创建子任务。整个系统有很多组件,这只是我希望查看的另一个数字,它可能会导致任何性能线索。所以不,我不需要知道,但这会很有趣。
  • @pm100 是的,这就是我要找的。​​span>
  • @Cuthbert 不,他没有做错!我们需要能够观察系统的健康状况:线程池的线程数是由 .NET 自动调整的,但是您如何知道您的代码运行良好或即将死亡?您可以观察线程池队列长度,它不能永久增加。

标签: c# multithreading


【解决方案1】:

我还没有找到获取线程池中等待执行的任务数的方法。

但我找到了一种方法来监控线程池运行状况

我创建了一个全局计时器(假设每 5 秒一次),并测量上一个“Elapsed”的延迟: 由于Microsoft .NET Timers是在ThreadPool中执行的,如果延迟异常,比如7秒,我知道Elapsed要等很久,所以ThreadPool已经饱和了。

【讨论】:

    【解决方案2】:

    有一个 ThreadPool.PendingWorkItemCount 属性。

    https://docs.microsoft.com/en-us/dotnet/api/system.threading.threadpool.pendingworkitemcount?view=netcore-3.1

    如果您正在运行 .net 核心,另一种可能性是运行 dotnet counters monitor --process-id 123

    这将为您提供一些运行时指标的控制台显示。我相信你问的指标是倒数第三个。

    Press p to pause, r to resume, q to quit.
        Status: Running
    
    [System.Runtime]
        % Time in GC since last GC (%)                         0
        Allocation Rate / 1 sec (B)                       66,480
        CPU Usage (%)                                          0
        Exception Count / 1 sec                                0
        GC Heap Size (MB)                                    234
        Gen 0 GC Count / 60 sec                                0
        Gen 0 Size (B)                               200,991,744
        Gen 1 GC Count / 60 sec                                0
        Gen 1 Size (B)                                   385,440
        Gen 2 GC Count / 60 sec                                0
        Gen 2 Size (B)                               210,807,272
        LOH Size (B)                                  74,140,000
        Monitor Lock Contention Count / 1 sec                  0
        Number of Active Timers                              314
        Number of Assemblies Loaded                          272
        ThreadPool Completed Work Item Count / 1 sec          38
        ThreadPool Queue Length                                0
        ThreadPool Thread Count                                9
        Working Set (MB)                                     242
    

    一些有用的链接:

    https://docs.microsoft.com/en-us/dotnet/core/diagnostics/dotnet-counters https://www.youtube.com/watch?v=jn54CjePzs0

    【讨论】:

      【解决方案3】:

      我使用一种简单的方法来了解有多少 Task.Run 正在等待 ThreadPool 执行,方法是在我调用 Task.Run 时增加一个计数器并在代码真正执行时减少它:

      long waitingTaskCount = 0; // Current number of Tasks waiting for execution
      long executedTasksCount = 0; // Total number of executed Tasks
      long totalWaitingTimeMs = 0; // Total waiting time in ms
      
      void ExecutingMethod()
      {
          Interlocked.Increment(ref waitingTaskCount);
          Stopwatch swTaskWaitingTime = Stopwatch.StartNew();
          Task.Run(() =>
          {
              Interlocked.Decrement(ref waitingTaskCount);
              Interlocked.Increment(ref executedTasksCount); 
              Interlocked.Add(ref totalWaitingTimeMs ,swTaskWaitingTime.ElapsedMilliseconds;    
              // (...)
          };
      }
      

      我还添加了一个等待时间计数器和一个任务执行计数。

      • 所以要获得以毫秒为单位的平均等待时间,只需计算 totalWaitingTimeMs / executedTasksCount
      • 您在 waitingTaskCount 中有当前等待的任务

      【讨论】:

        猜你喜欢
        • 2018-07-24
        • 1970-01-01
        • 1970-01-01
        • 2015-07-13
        • 2015-08-29
        • 2010-10-16
        • 2013-01-23
        • 1970-01-01
        相关资源
        最近更新 更多