并行Foreach内存问题

Jay*_*ena 6 .net multithreading plinq

我在FileInfoCollection中有一个文件集(3000个文件).我想通过应用一些独立的逻辑来处理所有文件(可以并行执行).

 FileInfo[] fileInfoCollection = directory.GetFiles();
 Parallel.ForEach(fileInfoCollection, ProcessWorkerItem);
Run Code Online (Sandbox Code Playgroud)

但在处理了大约700个文件后,我收到内存不足错误.我之前使用过Thread-pool,但它给出了同样的错误.如果我尝试在没有线程的情况下执行(并行处理),它可以正常工作.

在"ProcessWorkerItem"中,我正在运行基于文件的字符串数据的算法.另外,我使用log4net进行日志记录,并且在此方法中与SQL服务器进行了大量通信.

以下是一些信息,文件大小:1-2 KB XML文件.我读了那些文件,这个过程取决于文件的内容.它识别字符串中的一些关键字并生成另一种XML格式.关键字在SQL服务器数据库中(近2000字).

Jon*_*eet 7

那么,做ProcessWorkerItem什么?您可以更改使用较少的内存(如流中的数据,而不是加载这一切在一次),或者你可能想明确地限制并行的使用程度这个过载ParallelOptions.MaxDegreeOfParallelism.基本上你想避免尝试一次处理所有3000个文件:) IIRC,Parallel Extensions将"注意到"你的任务是否似乎是IO绑定的,并允许一次执行超过正常数量 - 这实际上不是什么你想在这里,因为你也有记忆.

  • @Jayantha:但你还是*还没有解释你对文件做了什么,或者它们有多大,或者为什么你的内存不足.如果你正在做一些每个文件需要1GB的东西,那么你一次不能处理超过两个或者三个......而如果你正在做一些微不足道的事情,你可能会处理数百个. (2认同)
  • @Jayantha:我开始摆脱并行性.你可以连续运行整个系列吗?如果是这样,听起来好像你只需要降低并行度.如果没有,请将探查器拿出来,检查哪些物体不应该悬挂在周围. (2认同)

Jay*_*ena 0

我发现了引发内存泄漏的错误,我将工作单元模式与实体框架一起使用。在工作单元中,我将上下文保存在哈希表中,并以线程名称作为哈希键。当我使用线程时,哈希表不断增长,并导致内存泄漏。因此,我向工作单元添加了额外的方法,以在完成线程的任务后从哈希表中删除元素。

public static void DisposeUnitOfWork()
        {
            IUnitOfWork unitOfWork = GetUnitOfWork();

            if (unitOfWork != null)
            {
                unitOfWork.Dispose();
                hashTable.Remove(Thread.CurrentThread.Name);


            }
        }
Run Code Online (Sandbox Code Playgroud)