由于 FileSystemWatcher 的内存限制,c# ThreadPool 使用的线程少于内核
c# ThreadPool using less threads than cores because of memory restrictions with FileSystemWatcher
我有一个大量的图像计算任务,它使用大约 1GB 的内存(一个计算周期大约需要 4 秒)。当它们到达文件夹时,我使用 FileSystemWatcher 自动处理这些图像。当 FileSystemWatcher 为新文件触发事件时,我将事件处理程序方法中的工作排队:
private void OnNewFileInDir(object source, FileSystemEventArgs evtArgs)
{
ThreadPool.QueueUserWorkItem(new WaitCallback(ProcessTheNewImage), evtArgs.FullPath);
}
我的问题是当文件快速到达时程序经常崩溃。在调试 window 中,我可以看到那一刻使用了近 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();
}
Threadpool 的资源管理形式非常有限。当队列填满时,它会慢慢地继续添加线程。它适用于相对较小(< 500 毫秒)的作业。没有安全阀可以阻止它堵塞您的应用程序。
您可以为此创建一个工作流程:观察者事件将简单的数据包推送到 ConcurrentQueue 中,然后您创建 2 个或更多线程(更好:任务)来处理队列。这将允许您调整线程数。
我有一个大量的图像计算任务,它使用大约 1GB 的内存(一个计算周期大约需要 4 秒)。当它们到达文件夹时,我使用 FileSystemWatcher 自动处理这些图像。当 FileSystemWatcher 为新文件触发事件时,我将事件处理程序方法中的工作排队:
private void OnNewFileInDir(object source, FileSystemEventArgs evtArgs)
{
ThreadPool.QueueUserWorkItem(new WaitCallback(ProcessTheNewImage), evtArgs.FullPath);
}
我的问题是当文件快速到达时程序经常崩溃。在调试 window 中,我可以看到那一刻使用了近 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();
}
Threadpool 的资源管理形式非常有限。当队列填满时,它会慢慢地继续添加线程。它适用于相对较小(< 500 毫秒)的作业。没有安全阀可以阻止它堵塞您的应用程序。
您可以为此创建一个工作流程:观察者事件将简单的数据包推送到 ConcurrentQueue 中,然后您创建 2 个或更多线程(更好:任务)来处理队列。这将允许您调整线程数。