ThreadPool - MaxThreads - AvailableThreads = ThreadPool 线程的当前数量吗?
ThreadPool - Does MaxThreads - AvailableThreads = CUrrent Number Of ThreadPool Threads?
以下是否可以提供准确的 ThreadPool 线程数 运行?
ThreadPool.GetAvailableThreads(out var availableWorkerThreads, out var availableCompletionPortThreads);
ThreadPool.GetMaxThreads(out var maxWorkerThreads, out var maxCompletionPortThreads);
var currentWorkerThreads = maxWorkerThreads - availableWorkerThreads;
var currentCompletionPortThreads = maxCompletionPortThreads - availableCompletionPortThreads;
Console.WriteLine("Current Worker Threads: " + currentWorkerThreads)
Console.WriteLine("Current Completion Port Threads: " + currentCompletionPortThreads)
是
看来您确实可以使用它来计算活动线程池线程数。
至少在 .NET Framework 4.6.1 上
测试
我写了一个 noddy 控制台应用来测试这个,通过安排一堆任务,看看有多少线程被创建。
您可以看到在 4 之后它会等待一段时间再创建其他线程。
输出
---- Start ---- 17:01:55.2583
ThreadPool.GetAvailableThreads: 2,047
ThreadPool.GetMaxThreads: 2,047
ThreadPool.GetMinThreads: 4
ThreadPool.CurrentThreads: 0
---- After Scheduling 1 ---- 17:01:55.2793
ThreadPool.GetAvailableThreads: 2,046
ThreadPool.GetMaxThreads: 2,047
ThreadPool.GetMinThreads: 4
ThreadPool.CurrentThreads: 1
---- After Scheduling 50 ---- 17:01:55.2803
ThreadPool.GetAvailableThreads: 2,043
ThreadPool.GetMaxThreads: 2,047
ThreadPool.GetMinThreads: 4
ThreadPool.CurrentThreads: 4
---- After Scheduling 500 ---- 17:01:55.2813
ThreadPool.GetAvailableThreads: 2,043
ThreadPool.GetMaxThreads: 2,047
ThreadPool.GetMinThreads: 4
ThreadPool.CurrentThreads: 4
---- After Sleeping 30.00s ---- 17:02:25.3403
ThreadPool.GetAvailableThreads: 2,022
ThreadPool.GetMaxThreads: 2,047
ThreadPool.GetMinThreads: 4
ThreadPool.CurrentThreads: 25
---- After Sleeping 30.00s ---- 17:02:55.3453
ThreadPool.GetAvailableThreads: 2,004
ThreadPool.GetMaxThreads: 2,047
ThreadPool.GetMinThreads: 4
ThreadPool.CurrentThreads: 43
---- After Waiting for all 500 ---- 17:03:25.3573
ThreadPool.GetAvailableThreads: 2,047
ThreadPool.GetMaxThreads: 2,047
ThreadPool.GetMinThreads: 4
ThreadPool.CurrentThreads: 0
代码
class Program
{
private static readonly List<Task> _tasks = new List<Task>();
static void Main(string[] args)
{
OutputThreadCount("Start");
var millisecondsDelay = 5000;
ScheduleTasks(1, millisecondsDelay);
OutputThreadCount("After Scheduling 1");
ScheduleTasks(50, millisecondsDelay);
OutputThreadCount("After Scheduling 50");
ScheduleTasks(500, millisecondsDelay);
OutputThreadCount("After Scheduling 500");
var all = Task.WhenAll(_tasks);
while (!all.IsCompleted)
{
var millisecondsTimeout = TimeSpan.FromSeconds(30);
Thread.Sleep(millisecondsTimeout);
OutputThreadCount($"After Sleeping {millisecondsTimeout.TotalSeconds:N2}");
}
OutputThreadCount("After Waiting for all 500");
Console.Read();
}
private static void ScheduleTasks(int taskCount, int millisecondsDelay)
{
for (int i = 0; i < taskCount; i++)
{
var task = Task.Run(() => Thread.Sleep(millisecondsDelay));
_tasks.Add(task);
}
}
private static void OutputThreadCount(string message)
{
Console.WriteLine();
Console.WriteLine($"---- {message} ---- {DateTime.UtcNow:HH:mm:ss.ffff}");
ThreadPool.GetAvailableThreads(out var availableWorkerThreads, out var availableCompletionPortThreads);
ThreadPool.GetMaxThreads(out var maxWorkerThreads, out var maxCompletionPortThreads);
ThreadPool.GetMinThreads(out var minWorkerThreads, out var minCompletionPortThreads);
Console.WriteLine($"ThreadPool.GetAvailableThreads: {availableWorkerThreads:N0}");
Console.WriteLine($"ThreadPool.GetMaxThreads: {maxWorkerThreads:N0}");
Console.WriteLine($"ThreadPool.GetMinThreads: {minWorkerThreads:N0}");
Console.WriteLine($"ThreadPool.CurrentThreads: {maxWorkerThreads - availableWorkerThreads:N0}");
Console.WriteLine();
}
}
以下是否可以提供准确的 ThreadPool 线程数 运行?
ThreadPool.GetAvailableThreads(out var availableWorkerThreads, out var availableCompletionPortThreads);
ThreadPool.GetMaxThreads(out var maxWorkerThreads, out var maxCompletionPortThreads);
var currentWorkerThreads = maxWorkerThreads - availableWorkerThreads;
var currentCompletionPortThreads = maxCompletionPortThreads - availableCompletionPortThreads;
Console.WriteLine("Current Worker Threads: " + currentWorkerThreads)
Console.WriteLine("Current Completion Port Threads: " + currentCompletionPortThreads)
是
看来您确实可以使用它来计算活动线程池线程数。
至少在 .NET Framework 4.6.1 上
测试
我写了一个 noddy 控制台应用来测试这个,通过安排一堆任务,看看有多少线程被创建。
您可以看到在 4 之后它会等待一段时间再创建其他线程。
输出
---- Start ---- 17:01:55.2583
ThreadPool.GetAvailableThreads: 2,047
ThreadPool.GetMaxThreads: 2,047
ThreadPool.GetMinThreads: 4
ThreadPool.CurrentThreads: 0
---- After Scheduling 1 ---- 17:01:55.2793
ThreadPool.GetAvailableThreads: 2,046
ThreadPool.GetMaxThreads: 2,047
ThreadPool.GetMinThreads: 4
ThreadPool.CurrentThreads: 1
---- After Scheduling 50 ---- 17:01:55.2803
ThreadPool.GetAvailableThreads: 2,043
ThreadPool.GetMaxThreads: 2,047
ThreadPool.GetMinThreads: 4
ThreadPool.CurrentThreads: 4
---- After Scheduling 500 ---- 17:01:55.2813
ThreadPool.GetAvailableThreads: 2,043
ThreadPool.GetMaxThreads: 2,047
ThreadPool.GetMinThreads: 4
ThreadPool.CurrentThreads: 4
---- After Sleeping 30.00s ---- 17:02:25.3403
ThreadPool.GetAvailableThreads: 2,022
ThreadPool.GetMaxThreads: 2,047
ThreadPool.GetMinThreads: 4
ThreadPool.CurrentThreads: 25
---- After Sleeping 30.00s ---- 17:02:55.3453
ThreadPool.GetAvailableThreads: 2,004
ThreadPool.GetMaxThreads: 2,047
ThreadPool.GetMinThreads: 4
ThreadPool.CurrentThreads: 43
---- After Waiting for all 500 ---- 17:03:25.3573
ThreadPool.GetAvailableThreads: 2,047
ThreadPool.GetMaxThreads: 2,047
ThreadPool.GetMinThreads: 4
ThreadPool.CurrentThreads: 0
代码
class Program
{
private static readonly List<Task> _tasks = new List<Task>();
static void Main(string[] args)
{
OutputThreadCount("Start");
var millisecondsDelay = 5000;
ScheduleTasks(1, millisecondsDelay);
OutputThreadCount("After Scheduling 1");
ScheduleTasks(50, millisecondsDelay);
OutputThreadCount("After Scheduling 50");
ScheduleTasks(500, millisecondsDelay);
OutputThreadCount("After Scheduling 500");
var all = Task.WhenAll(_tasks);
while (!all.IsCompleted)
{
var millisecondsTimeout = TimeSpan.FromSeconds(30);
Thread.Sleep(millisecondsTimeout);
OutputThreadCount($"After Sleeping {millisecondsTimeout.TotalSeconds:N2}");
}
OutputThreadCount("After Waiting for all 500");
Console.Read();
}
private static void ScheduleTasks(int taskCount, int millisecondsDelay)
{
for (int i = 0; i < taskCount; i++)
{
var task = Task.Run(() => Thread.Sleep(millisecondsDelay));
_tasks.Add(task);
}
}
private static void OutputThreadCount(string message)
{
Console.WriteLine();
Console.WriteLine($"---- {message} ---- {DateTime.UtcNow:HH:mm:ss.ffff}");
ThreadPool.GetAvailableThreads(out var availableWorkerThreads, out var availableCompletionPortThreads);
ThreadPool.GetMaxThreads(out var maxWorkerThreads, out var maxCompletionPortThreads);
ThreadPool.GetMinThreads(out var minWorkerThreads, out var minCompletionPortThreads);
Console.WriteLine($"ThreadPool.GetAvailableThreads: {availableWorkerThreads:N0}");
Console.WriteLine($"ThreadPool.GetMaxThreads: {maxWorkerThreads:N0}");
Console.WriteLine($"ThreadPool.GetMinThreads: {minWorkerThreads:N0}");
Console.WriteLine($"ThreadPool.CurrentThreads: {maxWorkerThreads - availableWorkerThreads:N0}");
Console.WriteLine();
}
}