1

私の同僚と私は、C# の Graphics クラスで明らかなバグに遭遇しました。このアプリケーションでは、ビットマップの上に新しいものを描画することで、時間の経過とともにビットマップを更新します。Graphics.DrawImage(Image, Rectangle) メソッドを使用すると、呼び出しが返されないか、例外がスローされることさえあります。それはあなたの誰かがよく知っている問題ですか?

ユースケースは次のとおりです。

Bitmap whole = ...;

これは、問題が発生するかなり前に定義されています。通常の呼び出しは次のようになり、「part」と「region」がネットワークから着信します。

Bitmap part = ...;
Rectangle region = ...;

using(var graphics = Graphics.FromImage(whole))
{
   using(part)
   {
      graphics.DrawImage(part, region); // Execution stops in here
   }
}

タイムアウトを設定してみました:

...
      var someAttributes = ... part ...;

      var drawing = Task.Factory.StartNew(() => graphics.DrawImage(part, region));

      if (!drawing.Wait(5000))
      {
        // We put a breakpoint here
      }
...

「part」画像を調べてみました。通話前は問題ないようです。破棄されたりはせず、そのプロパティを取得できます。しかし、呼び出しの後、そのすべてのメンバーが InvalidOperationException をスローします。

この後もプログラムを続行すると、次の呼び出しが毎回ハングします。しばらくしてデバッガーを一時停止すると、これらの「描画」タスクがまだ待機していることをスレッド ビューで確認できます。

したがって、回避策またはこの動作を防ぐ方法を知っている場合は、助けていただければ幸いです。

直後に編集:

グラフィックス オブジェクトを調べたところ、このオブジェクトは「現在別の場所で使用されている」ため、検査できないことがわかりました。これが「全体」イメージへの唯一の参照であると考えました。画像を複製して、画像ボックスに表示することもできました。Clone について調べたところ、正しく理解できていれば、Clone は浅いコピーのみを行い、古いイメージとリソースを共有していることがわかりました。

そこで交換してみました

Rectangle subregion = ...;
Bitmap copy = whole.Clone(subregion);

Rectangle subregion = ...;
Bitmap copy = new Bitmap(whole.Clone(subregion));

そして、それは私たちの問題を解決したようです. その場合、 DrawImage が例外をスローしないことはまだ問題ですが。

4

0 に答える 0