使用Graphics.DrawArc重现崩溃

wal*_*pus 6 .net graphics

我们的软件提供技术图纸.一个特定的绘图使应用程序每次都出现OutOfMemoryException崩溃.经过调查,似乎没有什么不寻常的; 该应用程序没有请求大量的内存,没有使用很多句柄.我尝试捕获异常,应用程序完成绘图而不抛出另一个.实际上,总是只有一个OutOfMemoryException,它始终是导致它的相同图形基元.

以下代码是导致此特定崩溃所需的最低要求.似乎图像大小,笔样式和坐标的确切组合导致异常.将坐标向下舍入到三位小数会使其消失,就像使图形尺寸更小或使用没有划线的笔一样.

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);
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,创建一个变通方法并不复杂,但我想知道是否有人对此有解释.

Han*_*ant 5

System.Drawing是GDI +的包装,GDI +是一个不受管理的库,它早于.NET的发布就已经很多年了。它遭受C api的典型问题,错误报告相当差。GDI +只有20个不同的错误代码,对于这么大的代码块来说却不多。它们也是非常不透明的,特别的问题是Status :: GenericError。对于许多没有共同点的可能的错误情况,返回了一个非常常见的错误。

假定这些错误代码不是由设计描述的,那么System.Drawing几乎无法使这些错误代码更具描述性。Status :: OutOfMemory也适合该模式。它几乎不能做到这一点,但会生成表示同一件事的托管异常。遗憾的是,这也不是一个好选择,因为OutOfMemoryException在.NET中非常具体。

这里损失惨重,几乎没有赢家的方法。您只需要从表面上评估GDI +的错误报告,然后解决问题即可。在这种情况下,避免在极小的弧上使用虚线笔很有可能会解决您的问题。无论如何,您都看不到破折号图案。