我正在运行简单的控制台迁移。 我通过批量750件物品捆绑工作量,并通过以下方式将其发送到我的ThreadPool:
ThreadPool.QueueUserWorkItem(workerArray[i]._DoWork, i);
我在执行_DoWork方法时添加了一些日志,并输出:
Thread 1 started working...
Thread 2 started working...
Thread 1 is done working
超过400次
但是在每个开始和结束时,我还记录了通过输出运行的线程数 (我在SO中找到的):
((IEnumerable)System.Diagnostics.Process.GetCurrentProcess().Threads)
.OfType<System.Diagnostics.ProcessThread>()
.Where(t => t.ThreadState == System.Diagnostics.ThreadState.Running)
.Count();
但是为什么当我有超过100个启动线程并且还没有完成时它只输出2到4个线程?
=============
更多代码
这是排队工作的原因:
for (var i = 0; i < taskCount; i++)
{
int itemCount = queueLength;
if (i * queueLength + itemCount > journalIDs.Count)
itemCount = (journalIDs.Count) - (i * queueLength);
var queue = journalIDs.GetRange(i * queueLength, itemCount);
doneEvents[i] = new ManualResetEvent(false);
dbWorkers[i] = new DBWorker();
var loadedQueue = db.GetJournalByIDs(queue);
workerArray[i] = new JournalWorker(dbWorkers[i], loadedQueue, doneEvents[i]);
ThreadPool.QueueUserWorkItem(workerArray[i]._DoWork, i);
}
这是DoWork的作用:
public void _DoWork(Object pThreadContext){
int theThreadIndex = (int)pThreadContext;
Console.WriteLine("Thread {0} started...", theThreadIndex);
var threads = ((IEnumerable)System.Diagnostics.Process.GetCurrentProcess().Threads)
.OfType<System.Diagnostics.ProcessThread>()
.Where(t => t.ThreadState == System.Diagnostics.ThreadState.Running)
.Count();
Console.WriteLine("There's {0} thread(s) currently running", threads);
foreach (var item in Queue)
{
var update = ShouldUpdate(item);
if (update != null)
{
//Do some db operation
}
else
{
//Do some db operation
}
}
Console.WriteLine("Thread {0} started saving...", theThreadIndex);
Save(Store);
Console.WriteLine("Thread {0} done working with " + Store.Count + " objects...", theThreadIndex);
threads = ((IEnumerable)System.Diagnostics.Process.GetCurrentProcess().Threads)
.OfType<System.Diagnostics.ProcessThread>()
.Where(t => t.ThreadState == System.Diagnostics.ThreadState.Running)
.Count();
Console.WriteLine("There's {0} thread(s) currently running", threads);
db.Clear();
db = null;
_doneEvent.Set();
}
答案 0 :(得分:0)
这里有几件事需要考虑
ThreadPool最大并发线程默认基于.NET 4.0中的几个不同因素。您可以通过调用GetMaxThreads
等待ManualResetEvent时,ThreadState将是WaitSleepJoin,而不是Running
控制台是线程安全的,但在多线程场景中使用时,不会为您提供可预测,准确定时,正确排序的输出