计算 Parallel.ForEach 使用的线程数

Hug*_*une 6 .net c# multithreading .net-4.0 task-parallel-library

Parallel.ForEach如何确定(or Parallel.Invoke, or Parallel.For)的特定调用期间使用的线程数

我知道如何限制最大线程数,例如

Parallel.ForEach(myList, 
                 new ParallelOptions { MaxDegreeOfParallelism = 4 },
                 item => { doStuff(item); });
Run Code Online (Sandbox Code Playgroud)

我知道 Task.Parallel 库使用一些启发式方法来确定除当前线程之外在运行时使用的附加线程池线程的最佳数量;0 和 MaxDegreeOfParallelism 之间的某个值。

我想知道出于记录目的实际使用了多少线程:

Stopwatch watch = Stopwatch.StartNew();
Parallel.ForEach(myList, item => { doStuff(item); });
trace.TraceInformation("Task finished in {0}ms using {1} threads", 
       watch.ElapsedMilliseconds, NUM_THREADS_USED); 
Run Code Online (Sandbox Code Playgroud)

我主要是为了好奇而记录这些数据,并提高我的理解。它不必 100% 可靠,因为我不打算将它用于其他用途。

有没有办法获得这个数字,而不会对性能产生重大影响?

Ren*_*ogt 8

您可以使用(线程安全)列表来存储已使用线程的 ID 并对其进行计数:

ConcurrentBag<int> threadIDs = new ConcurrentBag<int>();
Parallel.ForEach(myList, item => { 
    threadIDs.Add(Thread.CurrentThread.ManagedThreadId);
    doStuff(item); 
});

int usedThreads = threadIDs.Distinct().Count();
Run Code Online (Sandbox Code Playgroud)

确实会对性能产生影响(尤其是线程安全逻辑ConcurrentBag),但我无法判断有多大。相对效果取决于其本身所做的工作量doStuff。如果该方法只有几个命令,则该线程计数解决方案甚至可能会更改所使用的线程数。