6

FileInfoCollectionにファイルコレクション(3000ファイル)があります。独立した(並列で実行できる)ロジックを適用して、すべてのファイルを処理したいと思います。

 FileInfo[] fileInfoCollection = directory.GetFiles();
 Parallel.ForEach(fileInfoCollection, ProcessWorkerItem);

しかし、約700個のファイルを処理した後、メモリ不足エラーが発生します。以前にスレッドプールを使用しましたが、同じエラーが発生していました。スレッド化(並列処理)せずに実行しようとすると、正常に動作します。

「ProcessWorkerItem」では、ファイルの文字列データに基づいてアルゴリズムを実行しています。さらに、ロギングにlog4netを使用しており、この方法ではSQLサーバーとの通信が多くなります。

ここにいくつかの情報があります、ファイルサイズ:1〜2KBのXMLファイル。私はそれらのファイルを読みました、そして、プロセスはファイルの内容に依存しています。文字列内のいくつかのキーワードを識別し、別のXML形式を生成しています。キーワードはSQLサーバーデータベースにあります(約2000語)。

4

3 に答える 3

7

さて、何をしProcessWorkerItemますか?使用するメモリを減らすように変更できる場合があります(たとえば、一度にすべてをロードする代わりにデータをストリーミングする)。または、このオーバーロードとを使用して並列処理の程度を明示的に制限することができますParallelOptions.MaxDegreeOfParallelism。基本的に、3000個のファイルすべてを一度に処理しようとしないようにします:) IIRC、Parallel Extensionsは、タスクがIOバウンドであるように見える場合に「通知」し、通常の数より多くを一度に実行できるようにします。あなたもメモリに縛られているので、あなたはここに欲しいです。

于 2011-05-11T08:36:39.910 に答える
2

大きなファイルを並行して操作しようとしている場合は、使用可能なメモリが不足する可能性があります。

たぶん、 Rx拡張機能を試して、そのスロットルメソッドを使用して処理を制御/構成することを検討しますか?

于 2011-05-11T08:38:39.910 に答える
0

エンティティフレームワークでUnitOfWorkパターンを使用しているときに、メモリリークを引き起こすバグを見つけました。作業単位では、ハッシュキーとしてスレッド名を使用してコンテキストをハッシュテーブルに保持します。スレッドを使用すると、ハッシュテーブルが大きくなり続け、メモリリークが発生します。そこで、スレッドのタスクを完了した後、ハッシュテーブルから要素を削除するためのメソッドを作業単位に追加しました。

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

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


            }
        }
于 2011-05-12T10:50:59.353 に答える