2017-04-08 4 views
1

ループをParallel.Forループを使用してパネルに描画することはできますか?私はdouble型の多次元配列double[][] plantsを持っており、配列の各エントリがパネル上のグリッド内の矩形として描画されるように、列を並行して描画したいと考えています。私がしようとすると、grapahics.FillRectangle()と行で Windowsフォーム平行描画

は、私はこのエラーを得続ける:

「System.InvalidOperationException」種類の例外がSystem.Drawing.dllで発生したが、ユーザーコードで処理されなかった

追加情報:オブジェクトは現在他の場所で使用されています。ここで

は、私が使用していたコードです:

Parallel.For(0, simWidth, i => 
     { 
      Color plantColor; 
      RectangleF plantRectangle= new Rectangle(); 
      SolidBrush plantBrush = new SolidBrush(Color.Black); 
      for (int j = 0; j < simHeight; ++j) 
      { 
       int r, g = 255, b; 
       r = b = (int)(255 * (Math.Tanh(simulation.plants[i, j]) + 1)/2.0); 
       plantColor = Color.FromArgb(100, r, g, b); 
       plantBrush.Color = plantColor; 
       plantRectangle.Location = new PointF(i * cellSize, j * cellSize); 
       graphics.FillRectangle(plantBrush, plantRectangle); 
      } 

      plantBrush.Dispose(); 
     }); 

を私は何が起こっていることは、グラフィックスオブジェクトは一度に複数のコールを処理することができないということだと思います。これを回避する方法はありますか?私は各並列呼び出しでグラフィックスオブジェクトへのローカル参照を作成しようとしましたが、うまくいきませんでした。

答えて

2

Parallel.Forループを使用してパネルに描画することはできますか?

いいえ、実際には役に立ちません。

PanelなどのUIオブジェクトには、「スレッドアフィニティ」があります。つまり、それらは特定のスレッドによって所有され、そのスレッドでのみ使用される必要があります。より多くのことができます。あなたのGraphicsオブジェクトのような

GDI +オブジェクトは、(、あなたのコード内の他の設計上の欠陥を持っていない場合は、そのオブジェクトを持ってどこに言うことはありませんが、一つは、それがPaintEventArgs&hellipであなたに渡された期待しています)寛容ですが、スレッドセーフではありません。オブジェクトの実際の使用を中心に同期を追加できますが、その使用は遅い部分です。それらをシリアライズすると、コード内の並行性の利点のほとんどが無効になります。

ここでParallelを使用しても、特定のパフォーマンス上の問題に対処する実際の試みであったかどうかはわかりません。 Windows Formsコードでのレンダリングパフォーマンスを向上させるためのさまざまな手法について議論しているStack Overflowには、多くの質問があります。

一般に、これらの手法のほとんどは、キャッシングによって実行される作業の総量を可能な限り削減します。あなたが示したコードに基づいて、あなたがやりたいことが少なくとも2つあります:

  1. 矩形と色の計算をキャッシュします。基礎となるパラメータが変わるたびに、計算の一部をParallelで実行することもできます。
  2. Bitmapオブジェクトにすべてを描画します。これはシングルスレッドで行う必要がありますが、a)UIオブジェクトを所有するUIスレッドで行う必要はありません。b)基礎となるパラメータが変わるたびに、これを1回だけ実行できます。 Bitmapに描画されている場合は、Paintイベントが発生したときには、最初からすべてを再描画するのではなく、Bitmapオブジェクトを描画することができます。
+0

'graphics'は' PaintEventArgs e'、 'e.Graphics'からのものでした。基本的にシミュレーションを「レンダリング」するので、私はそれを平行にすることを検討していました。良いアイデアのように 'Bitmap'サウンドをキャッシュして使用していただき、ありがとうございます! –

関連する問題