为什么运行线程的次数少于我发送给线程池的工作量

时间:2017-06-10 12:05:10

标签: c# .net multithreading

我正在运行简单的控制台迁移。 我通过批量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();


    }

1 个答案:

答案 0 :(得分:0)

这里有几件事需要考虑

  • ThreadPool最大并发线程默认基于.NET 4.0中的几个不同因素。您可以通过调用GetMaxThreads

  • 来检查实际值
  • 等待ManualResetEvent时,ThreadState将是WaitSleepJoin,而不是Running

  • 控制台是线程安全的,但在多线程场景中使用时,不会为您提供可预测,准确定时,正确排序的输出