1

私はこのバッファリングアルゴリズムを持っています

while (aufnahme || ArrayAnsammlung.Count > 1)
{
    if (ArrayAnsammlung != null)
    {
        int l = ArrayAnsammlung.Count - 1;
        //db(l.ToString());


        for (int DurchLaeufer = 0; DurchLaeufer < l; DurchLaeufer++)
        {
            if (ArrayAnsammlung[DurchLaeufer] != null)
            {
                Nummerierung = Convert.ToString(Nummerierungszaehler);
                Enkodierung = new JpegBitmapEncoder();
                Enkodierung.FlipHorizontal = true;
                //Enkodierung.FlipVertical = false;
                var dateiStrom = new FileStream("E:\\Temp\\" + datum + " " + Nummerierung.PadLeft(12, '0') + ".jpg", FileMode.Create);
                Enkodierung.Frames.Add(BitmapFrame.Create(BitmapSource.Create(bildbreite, bildhoehe * 2,
                96, 96, PixelFormats.Bgr32, null, ArrayAnsammlung[DurchLaeufer], stride)));
                Enkodierung.Save(dateiStrom);
                dateiStrom = null;
                Enkodierung = null;
                Nummerierungszaehler++;
            }
        }
        if (l > 0)
        {
            ArrayAnsammlung.RemoveRange(0, l);
        }
    }
    Thread.Sleep(60);
}
  • DurchLaeufer は単なるインデックスです。
  • ArrayAnsammlung は、各フィールドに画像データを含む配列です。そのため、for部分はバイト配列の内容を反復処理します。
  • これはすべて、別のスレッドでイメージが ArrayAnsammlung に書き込まれている間に実行されるスレッドで発生します。処理される (jpeg に変換される) よりも多くの画像が配信されるため、バッファーが必要です。
  • aufnahme は、画像データが ArrayAnsammlung に書き込まれているときに true になる bool です。
  • Nummerierung は、画像を分離するのに役立つカウンターです。

機能しますが、プロファイラーによると、負荷が高くなっています

while (aufnahme || ArrayAnsammlung.Count - 1 > 0)

アプリの動作が遅くなります。

どうすればこれを最適化したり、特に順序を台無しにすることなくこれで Parallel.For を使用したりできますか。したがって、並列で実行されている間、順序は for ループと同じでなければなりません。

PS:追加しました

Thread.Sleep(60);

それは仕事の負担を減らすのに役立ちますか?

4

2 に答える 2

3

周りの負荷が高いwhile (aufnahme || ArrayAnsammlung.Count - 1 > 0)

つまり、配列が空である間、多くのループが発生します。これは WaitHandle で解決できます。空のコレクションで CPU を浪費する理由はありません。

しかし、より良い簡単な解決策は、ConcurrenQueue<T>or a BlockingCollectionhere を使用することです。次に、この特定の問題を で解決できますmyQueue.Take()


わかりました、要求されたコード サンプル:

//untested

// the new definition
private BlockingCollection<byte[]> ArrayAnsammlung = new BlockingCollection<byte[]>();


while (aufnahme)
{
   byte[] data = ArrayAnsammlung.Take();

   if (data != null)
   {
     int localNum = Interlocked.Increment(ref Nummerierung);  // initialize it 1 lower

      ... // process data
   }
}

これが大雑把な考え方です。で停止する方法を確認することをお勧めしCompleteAdding()ます。


副次的な問題:

while (aufnahme || ArrayAnsammlung.Count - 1 > 0)
{
    if (ArrayAnsammlung != null)
    {

!= nullテストが遅すぎます。周囲のループで既に使用され.Countています。

于 2013-01-17T19:35:35.420 に答える
0

試してみませんか:

Thread.Sleep(0);

MSDNから: 「ゼロ (0) を指定して、このスレッドを中断し、他の待機中のスレッドを実行できるようにする必要があることを示します。」

于 2013-01-17T19:35:56.540 に答える