在一次性对象上未正确调用处置

Dispose not being called correctly on disposable object

我有一个函数可以将对象列表绘制到位图上以创建粗略的地图。代码分析会抛出一条警告 (CA2000),指出对象 'drawPen' 并未沿着所有异常路径进行处理。据我所知,它被放置在函数的末尾,并且没有无法访问的代码可能会被遗漏。

有谁知道为什么编译器认为它没有被正确处理?

public void drawUpdates(List<areaObjects> objectLocations)
{
    Rectangle areaToClone = new Rectangle(0, 0, writeOnceMap.Width, writeOnceMap.Height);
    var pixelFormat = writeOnceMap.PixelFormat;
    areaBitMap = writeOnceMap.Clone(areaToClone, pixelFormat);
    Pen drawPen = new Pen(Color.Black, 2);
    drawPen.Width = 2;
    foreach(areaObjectsop2d in objectLocations)
    {
        int xPosition = (int)(op2d.XYZ.xPos * mapScale);
        int yPosition = (int)(op2d.XYZ.yPos * mapScale);
        Point[] crossMarker = getCrossShape(xPosition, yPosition);

        using (var graphics = Graphics.FromImage(areaBitMap))
        {
            graphics.DrawPolygon(drawPen, crossMarker);
        }
    }
    drawPen.Dispose();
}

你收到警告是因为如果你的函数出现异常,drawPen 将不会被释放。

您可以将您的代码包装在 try finally 中,最后调用 .Dispose() 或更好的方法 - 使用 using 正是这样做的。

public void drawUpdates(List<areaObjects> objectLocations)
{
    Rectangle areaToClone = new Rectangle(0, 0, writeOnceMap.Width, writeOnceMap.Height);
    var pixelFormat = writeOnceMap.PixelFormat;
    areaBitMap = writeOnceMap.Clone(areaToClone, pixelFormat);
    using(Pen drawPen = new Pen(Color.Black, 2))
    {
        foreach(areaObjectsop2d in objectLocations)
        {
            int xPosition = (int)(op2d.XYZ.xPos * mapScale);
            int yPosition = (int)(op2d.XYZ.yPos * mapScale);
            Point[] crossMarker = getCrossShape(xPosition, yPosition);

            using (var graphics = Graphics.FromImage(areaBitMap))
            {
                graphics.DrawPolygon(drawPen, crossMarker);
            }
        }
    }
}

以上等同于:

Pen drawPen = new Pen(Color.Black, 2);
try
{
    /*Your code*/
}
finally
{
    drawPen.Dispose();
}

想象一下,如果在创建笔和处理笔之间的代码抛出异常会发生什么。笔不会被丢弃。编译器会警告您确保即使发生异常也会处理笔。您有两种方法可以这样做:usingtry...finally(实际上是 using 的实现)。

using (Pen drawPen = ...)
{
} // now the code makes sure it gets disposed