由于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();
}
线程池只有一种非常有限的资源管理形式。当队列填满时,它将缓慢地继续添加线程。它适用于相对较小的(<500毫秒)的工作。没有安全阀可以阻止它堵塞应用程序。
你可以为此创建一个工作流:观察者事件将简单的数据包推送到ConcurrentQueue中,然后你创建2个或更多的线程(最好是任务)来处理队列。这将允许您调整线程的数量。