由于FileSystemWatcher的内存限制,c#ThreadPool使用的线程少于内核

时间:2016-10-11 16:19:18

标签: c# multithreading thread-safety threadpool filesystemwatcher

我有一个广泛的图像计算任务,它使用大约1GB的内存(一个计算周期大约需要4秒)。当我们使用FileSystemWatcher到达文件夹时,我会自动处理这些图像。当FileSystemWatcher为新文件触发事件时,我使用eventhandler方法对工作进行排队:

private void OnNewFileInDir(object source, FileSystemEventArgs evtArgs)
{
    ThreadPool.QueueUserWorkItem(new WaitCallback(ProcessTheNewImage), evtArgs.FullPath); 
}

我的问题是,当文件快速到达时,程序会定期崩溃。在调试窗口中,我可以看到当时使用的是3GB内存。当我使用较小的图像以便使用较少的内存时,没有崩溃(到目前为止)。

我的问题:我可以做些什么来使用更少(可能只是2个)独立于我的计算机核心的线程?

或者我使用FileSystemWatcher将新文件提示给线程池完全愚蠢的方法是什么?我对线程比赛或类似的事情都没有经验。 所以,此外:这看起来是线程安全吗?

非常感谢前方和所有最好的

为了完整性,这里是由线程执行的代码(为了便于阅读,简化了一点):

private void ProcessTheNewImage(object threadFilenameInfo)
{
   String filename = (String)threadFilenameInfo;

   // Load the image
   Image currentImage = Image.FromFile(filename);

   //Calculate the image in an external DLL
   Image currentResultImage = ImageProcessing.getResultImage(currentImage);

   //Create the filename with the result infos
   string saveFileName = "blahblah";

   //Save the image
   currentResultImage.Save(saveFileName);

   //dispose the images
   currentImage.Dispose();
   currentResultImage.Dispose();
}

1 个答案:

答案 0 :(得分:3)

Threadpool只有非常有限的资源管理形式。当队列填满时,它将慢慢地继续添加线程。它适用于相对较小(<500毫秒)的作业。没有安全阀可以阻止它堵塞您的应用程序。

您可以为此创建一个工作流:watcher事件将简单数据包推入ConcurrentQueue,然后创建2个或更多Threads(更好:Tasks)来处理队列。这将允许您调整线程数。