2013-02-18 2 views
5

当社のソフトウェアは技術図面をレンダリングします。 1つの特定の図面は、OutOfMemoryExceptionで毎回アプリケーションをクラッシュさせました。調査の結果、何も普通のようには見えなかった。アプリケーションは、多くのメモリを要求していない、ハンドルの多くを使用していない。私は例外をキャッチしようとし、アプリは別のものを投げることなく描画を終了しました。実際には、常に1つしかありませんOutOfMemoryException、それは常にそれを引き起こした同じグラフィックプリミティブでした。Graphics.DrawArcを使用した再現可能なクラッシュ

この特定のクラッシュを引き起こすには、次のコードが最低限必要です。画像サイズ、ペンスタイル、座標の正確な組み合わせが例外を引き起こすようです。 3つの小数点以下を切り捨てると、グラフィックスのサイズを小さくするか、または破線を使わずにペンを使用するように、座標が消えます。

using (Bitmap b = new Bitmap(200, 200)) 
{ 
    using (Graphics g = Graphics.FromImage(b)) 
    { 
    using (Pen p = new Pen(Color.Black)) 
    { 
     p.DashPattern = new float[]{10.0f, 2.0f}; 

     RectangleF r = new RectangleF(
     BitConverter.ToSingle(new byte[]{0xD3, 0x56, 0xB3, 0x42}, 0), 
     BitConverter.ToSingle(new byte[]{0x87, 0x2D, 0x17, 0x43}, 0), 
     BitConverter.ToSingle(new byte[]{0xE2, 0x81, 0xD1, 0x3F}, 0), 
     BitConverter.ToSingle(new byte[]{0xE2, 0x81, 0xD1, 0x3F}, 0)); 
     float st = BitConverter.ToSingle(new byte[]{0x6B, 0xF6, 0x1A, 0x42}, 0); 
     float sw = BitConverter.ToSingle(new byte[]{0x6D, 0x33, 0x4F, 0x40}, 0); 

     g.DrawArc(p, r, st, sw); 
    } 
    } 
} 

は、このケースでは、回避策を作成するために、複雑ではないですが、誰かがこのについての説明があった場合、私は思っていました。

答えて

4

System.Drawingは、.NETのリリースを長年遡って更新したアンマネージドライブラリであるGDI +のラッパーです。それはC APIの典型的な問題に悩まされています。エラー報告はむしろ貧弱です。 GDI +には20個の異なるエラーコードしかありません。そのような大きなコードチャンクではあまりありません。それらも非常に不透明で、特定のDoozyはStatus :: GenericErrorです。一般的なものを持たない多くの考えられるエラー条件に対して返されるきわめて一般的なエラーです。

これらのエラーコードを設計的に説明できないものとすると、System.Drawingでこれらのエラーコードをより分かりやすくすることはできません。 Status :: OutOfMemoryはそのパターンにも適合します。それはほとんどできませんが、同じことを意味する管理例外が生成されます。悲しいことに、OutOfMemoryExceptionは.NETでは非常に限定的なので、どちらも素晴らしい選択ではありませんでした。

ここでは多くの方法で勝利を得ることができます。あなたはGDI +の貧弱なエラー報告を額面で受け取り、問題を修正する必要があります。この場合、非常に小さな弧に対して破線のペンを使用することを避けることは、あなたの問題を解決する可能性が高い。とにかくダッシュパターンを見ることはできません。

+0

非常に有益です、ありがとうございます。私には、GDIのエラー報告が非常に限定されているとは思われませんでした。 – waldrumpus

関連する問題