我有一项服务需要永远运行才能监控一台服务器。为了做到这一点,我有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();
}
你有什么建议吗?
答案 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(从上面的代码看起来它会运行,无论如何)。感谢有趣的问题。