0

私は約1GBのメモリを使用する広範な画像計算タスクを持っています(計算サイクルは約4秒かかります)。 FileSystemWatcherを使用してフォルダに到着すると、それらのイメージを自動的に処理します。 FileSystemWatcherは、私はEventHandlerの方法で作業をキューに新しいファイルのためのイベントを起動したとき:c#FileSystemWatcherのメモリ制限のためにコアよりもスレッド数が少ないThreadPool

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

どのようにクラッシュしますか? OutOfMemoryExceptionが発生していますか?もしそうなら、それを64ビットとしてコンパイルすることができます。 –

+0

ねえ、ごめんなさい、申し訳ありません:それは例外なくクラッシュしました。ちょうどこの小さなウィンドウが開きます... "プログラムxzyはもう動作しません"または英語で何を言いますか(ドイツ語: "xyz funktioniert nicht mehr") – CaptIglu

+0

あなたが記述している状況は、未処理の例外のようです。あなたが 'ProcessTheNewImage()'にtry/catchを置くと、どのプロセスが表示されるでしょうか。 –

答えて

3

スレッドプール非常に限定された形のリソース管理しかありません。キューがいっぱいになると、スレッドの追加が遅くなります。それは比較的小さい(< 500ms)ジョブのためのものです。アプリケーションの詰まりを防ぐ安全弁はありません。

ウォッチャーイベントは、単純なデータパケットをConcurrentQueueにプッシュし、次にキューを処理する2つ以上のスレッド(より良い:タスク)を作成します。これにより、スレッド数を調整することができます。

+0

ありがとう!それは今良いです!私はThreadPoolが "短い"ジョブのためのものだと読んだが、私は4秒短いです:)私は、ファイル名のリストまたはタプルを調べる2つまたは3つのタスクと、すでに処理されている場合はマーカーで試してみます。または、zhe並行キューとのより良い方法はありますか?並行キューとは何か? – CaptIglu

+0

'System.Collections.Concurrent.ConcurrentQueue'またはBlockingCollection(そのキューの周囲のプロデューサー/コンシューマーラッパー)を使用することがあります –

+0

ありがとう!私は今、私のコードを変更し、それは非常に大きな画像のための2つのタスクのために安定しているようだ。より小さな画像を使用して、私は同じように多くのタスクを実行することができます。基本的に私は一連のタスクを使用しました。配列の長さは、自分のコードのマルチスレッドを定義します。私は 'ConcurrentQueue'(' FileSystemWatcher'で埋められている)を常に見ている別のスレッドを使い、配列のスロットが空いているか、配列内のタスクが終了したときに次のファイルパスの新しいタスクを開始します。この時点で、処理されるファイルパスはキューからデキューされます。 – CaptIglu

関連する問題