我们遇到的情况是,我们使用 ThreadPool.QueueUserWorkItem() API 从作业队列中的项目的 for 循环生成多个线程来执行一些文件复制操作。作业队列包含大约 50 个项目(用于测试目的)。
我们预计最多不会。当系统无法腾出尽可能多的线程(使用更高的工作负载)时,会生成 50 个线程进行处理,甚至更少。但是当我们打印号码时。使用 ThreadPool.GetAvailableThreads(out _iWorkerThreads, out _ioThreads) 获取池中可用线程的数量,我们得到常量 1023(对于工作线程的作业大小 50),并且没有 I/O 线程的数据。
不知道为什么会产生这么多线程。ThreadPool.GetAvailableThreads 的输出可靠吗?设置线程池中的最大线程数有帮助吗?评估平均数的可靠方法是什么?池中进程正在使用的托管线程数?
谁能指出为什么应用程序运行时 CPU 利用率几乎达到 100%。该代码使用 WaitHandles(通常是 ManualResetEvents)附加到每个作业,用于向主线程发出作业完成的信号。
这不是生成的线程数。这是在达到最大值之前可以生成的额外线程数。
MSDN:ThreadPool.GetAvailableThreads 方法
GetMaxThreads 减去 GetAvailableThreads 可能就是您要查找的数字。
不做任何事情:
class Program
{
static void Main(string[] args) {
int workerThreads, completionPortThreads;
ThreadPool.GetAvailableThreads(out workerThreads, out completionPortThreads);
Console.WriteLine(workerThreads);
Console.WriteLine(completionPortThreads);
Console.ReadLine();
}
}
Run Code Online (Sandbox Code Playgroud)
输出是:
1023
1000
Run Code Online (Sandbox Code Playgroud)
如果您确保在知道某些线程仍在工作时调用 ThreadPool.GetAvailableThreads,则该数字应该更低。
例子:
static void Main(string[] args) {
int workerThreads, completionPortThreads;
ThreadPool.GetAvailableThreads(out workerThreads, out completionPortThreads);
Console.WriteLine(workerThreads);
Console.WriteLine(completionPortThreads);
Console.WriteLine();
ThreadPool.QueueUserWorkItem(o => Thread.Sleep(10000));
ThreadPool.GetAvailableThreads(out workerThreads, out completionPortThreads);
Console.WriteLine(workerThreads);
Console.WriteLine(completionPortThreads);
Console.ReadLine();
}
Run Code Online (Sandbox Code Playgroud)
输出是:
1023
1000
1022
1000
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2141 次 |
| 最近记录: |