2

bool IsExistImage(int i)プロシージャがあります。画像を検出し、存在するかどうかに関係なく bool を返すプロシージャのタスク。

私は 100 ページ以上の PDF を持っており、それを分割してメソッドを介してファイル名のみを送信します。ファイル名は、実際にはメインの PDF ファイルのページ番号です。1,2,3,...,125,..のように

画像を検出した後、私のメソッドはページのリストを正しく保存します。そのために私はこのコードを使用しました:

ArrayList array1 = new ArrayList();
for(int i=1;i<pdf.length;i++)
{
   if(isExistImage(i))
   {
       array1.add(i);
   }
}

このプロセスは 1 時間以上実行されます (明らかに isExistImage() メソッドの内部作業のためです)。オブジェクト/変数がメソッドスコープの外でグローバルではないことを保証できます。

そこで、時間を短縮するために、Task.Parallel For ループを使用しました。これが私がしたことです:

System.Threading.Tasks,Parallel.For(1,pdf.Length,i =>
{
    if(isExistImage(i))
        array1.Add(i);
}

しかし、これは正しく機能していません。画像検出が正しい場合もあります。しかし、ほとんどの場合、それは間違っています。非並列 for ループを使用すると、常に正しい結果が得られます。

ここで何が問題なのか理解できません。ここで何を適用すればよいですか。私が見逃しているテクニックはありますか?

4

2 に答える 2

3

問題は、ArrayList(および他のほとんどの .Net コレクション) がスレッドセーフではないことです。

これを修正するにはいくつかの方法がありますが、この場合、最適なオプションは PLINQ を使用することだと思います。

List<int> pagesWithImages = ParallelEnumerable.Range(1, pdf.Length)
    .Where(i => isExistImage(i))
    .ToList();

これは、複数のスレッドを使用して(奇妙な名前の)isExistImageメソッドを呼び出します。これはまさにあなたが望むものでありList<int>、条件に一致したインデックスを含む を返します。

返されるリストはソートされません。必要に応じて、AsOrdered()の前に追加しWhere()ます。

ところで、あなたは本当に使用すべきではありませんArrayList。整数のリストが必要な場合は、 を使用しますList<int>

于 2013-12-16T17:43:43.450 に答える
0
  1. ArrayList はスレッド セーフではありません。ここで並行コレクションを調べてください。

  2. isExistImage はスレッドセーフですか? つまり、メンバー変数を更新する前にロックしていますか??

于 2013-12-16T14:09:27.007 に答える