私の同僚と私は、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 が例外をスローしないことはまだ問題ですが。