OutOfMemory Exception C#使用线程时

时间:2011-12-30 04:23:53

标签: c# multithreading threadpool out-of-memory

我有一项服务需要永远运行才能监控一台服务器。为了做到这一点,我有5个任务需要由服务完成(目前5个,将有数百个)。

我创建了一个最多包含5个线程的线程池。线程使用一个队列来获取任务,然后每个线程处理该任务,然后再次将其排队。队列包含具有5个小属性的对象。

服务运行一段时间后,我在执行此行的行中得到一个OutOfMemoryException:

ThreadPool.QueueUserWorkItem(currentJob.ProcessJob, (object)timeToWwait);

timeToWwait是一个int,我不再使用它了。

上下文是这样的:

        ThreadPool.SetMinThreads(0, 0);
        ThreadPool.SetMaxThreads(5, 5);
        while (true)
        {
            bool processJob = false;
            bool checkedFrontEnd = false;
            _qLock.EnterWriteLock();
            try
            {
                if (_jobQueue.Count > 0)
                {
                    currentJob = _jobQueue.Dequeue();
                    // currentJob.IsActive = true;
                    // processJob = true;
                }
            }
            finally
            {
                _qLock.ExitWriteLock();
            }
            ThreadPool.QueueUserWorkItem(currentJob.ProcessJob, (object)timeToWwait);
            //currentJob.ProcessJob((object)timeToWwait);


            _qLock.EnterWriteLock();
            try
            {
                _jobQueue.Enqueue(currentJob);
            }
            finally
            {
                _qLock.ExitWriteLock();
            }

你有什么建议吗?

2 个答案:

答案 0 :(得分:2)

您的问题是您在后台任务有机会完成之前将currentJob实例加入队列。你会想做这样的事情:

        ThreadPool.QueueUserWorkItem((state) =>
                                         { 
                                             currentJob.ProcessJob();
                                             _qLock.EnterWriteLock();
                                             try
                                             {
                                                 _jobQueue.Enqueue(currentJob);
                                             }
                                             finally
                                             {
                                                 _qLock.ExitWriteLock();
                                             } 

                                         }
            );

答案 1 :(得分:1)

看起来你可能只想在工作线程完成后再次将作业排入队列(到jobQueue)。想象一下,池中只有1个线程,jobQueue中只有1个作业,如果作业长时间运行,您的代码将在同一个作业上多次执行ThreadPool.QueueUserWorkItem。另外我认为你只想在jobQueue中有一个作业时执行ThreadPool.QueueUserWorkItem(从上面的代码看起来它会运行,无论如何)。感谢有趣的问题。