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

本文关键字:线程 内核 ThreadPool 内存 FileSystemWatcher 由于 | 更新日期: 2023-09-27 18:12:31

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

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();
}

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

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

你可以为此创建一个工作流:观察者事件将简单的数据包推送到ConcurrentQueue中,然后你创建2个或更多的线程(最好是任务)来处理队列。这将允许您调整线程的数量。