【发布时间】:2021-10-13 14:07:27
【问题描述】:
我正在开发一个程序,在该程序中我们不断启动新线程以启动并完成一项工作。我们注意到,即使我们可能启动了 10 个线程,一次也只有 3 或 4 个线程在执行。为了测试它,我做了一个这样的基本示例:
private void startThreads()
{
for (int i = 0; i < 100; i++)
{
//Task.Run(() => someThread());
//Thread t = new Thread(() => someThread());
//t.Start();
ThreadPool.QueueUserWorkItem(someThread);
}
}
private void someThread()
{
Thread.Sleep(1000);
}
简单的东西对吗?好吧,代码创建了 100 个线程,它们开始执行……但一次只有 3 或 4 个。当它们完成时,下一个线程开始执行。我本来预计几乎所有这些都同时开始执行。对于 100 个线程(每个线程有 1 秒的睡眠时间),所有线程大约需要 30 秒才能完成。我原以为它会花费比这更少的时间。
我尝试过使用Thread.Start、ThreadPool 和Tasks,都给了我完全相同的结果。如果我使用ThreadPool 并在每次线程运行时检查可用线程数,那么总是有 >2000 个可用工作线程和 1000 个可用异步线程。
我只是用上面的代码来测试我们的代码,试图找出发生了什么。在实践中,代码会在所有地方产生线程。该程序以不到 5% 的 CPU 使用率运行,但由于线程执行速度不够快而变得非常缓慢。
【问题讨论】:
-
but only 3 or 4 at a time.你的机器有什么确切 CPU? -
您能否使用您的应用程序方法运行
ThreadPool.GetMaxThreads并共享此方法返回的值。 -
您使用
QueueUserWorkItem和Task.Run有什么特别的原因吗? stackoverflow.com/questions/38880743/… -
这能回答你的问题吗? ThreadPool not starting new Thread instantly 具体来说,Jim 的 answer。如果您想立即启动线程,请使用 SetMinThreads。
-
附带说明,
someThread是一个糟糕的方法名称。 Microsoft's guidelines:1。使用动词或动词短语来命名方法。 2. 使用 Pascal 大小写。DoWork、ProcessItem、PutAThreadToSleep是一些更好的名称示例。
标签: c# .net multithreading threadpool