.net 使用Graphics.DrawArc再现碰撞

.net 使用Graphics.DrawArc再现碰撞,.net,graphics,.net,Graphics,我们的软件绘制技术图纸。一个特定的绘图使应用程序每次崩溃时都会出现OutOfMemoryException。经过调查,似乎没有什么不寻常的事情;该应用程序没有请求太多内存,也没有使用太多句柄。我尝试捕捉异常,应用程序完成了绘图,没有抛出另一个异常。事实上,总是只有一个OutOfMemoryException,并且总是同一个图形原语导致了它 以下代码是导致此特定崩溃所需的最低代码。似乎是图像大小、笔样式和坐标的精确组合导致了例外。将坐标四舍五入到三位小数将使其消失,使图形尺寸更小或使用钢笔而不使用

我们的软件绘制技术图纸。一个特定的绘图使应用程序每次崩溃时都会出现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);
    }
  }
}

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

System.Drawing是GDI+的包装,GDI+是一个非托管库,比.NET的发布早了很多年。它有一个典型的C api问题,错误报告相当糟糕。GDI+只有20个不同的错误代码,对于如此大的代码块来说,这并不多。它们也非常不透明,一个特别的问题是Status::genericerro。这是一个非常常见的错误,它针对许多可能的错误条件返回,这些错误条件没有任何共同之处

由于这些错误代码不是设计上的描述性代码,所以系统图纸对于使这些错误代码更具描述性几乎无能为力。状态::OutOfMemory也符合这种模式。它只能生成一个托管异常,这意味着同样的事情。遗憾的是,这也不是一个很好的选择,因为OutOfMemoryException在.NET中非常具体


这里有很多失败,几乎没有赢家。你只需要从表面上看GDI+的错误报告很差,然后修补这个问题。在这种情况下,避免使用虚线笔画非常小的弧很有可能解决您的问题。无论如何,您都看不到破折号模式。

非常有用,谢谢。我没有想到GDI错误报告可能会如此有限。