在一次性对象上未正确调用处置
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();
}
想象一下,如果在创建笔和处理笔之间的代码抛出异常会发生什么。笔不会被丢弃。编译器会警告您确保即使发生异常也会处理笔。您有两种方法可以这样做:using
和 try...finally
(实际上是 using
的实现)。
using (Pen drawPen = ...)
{
} // now the code makes sure it gets disposed
我有一个函数可以将对象列表绘制到位图上以创建粗略的地图。代码分析会抛出一条警告 (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();
}
想象一下,如果在创建笔和处理笔之间的代码抛出异常会发生什么。笔不会被丢弃。编译器会警告您确保即使发生异常也会处理笔。您有两种方法可以这样做:using
和 try...finally
(实际上是 using
的实现)。
using (Pen drawPen = ...)
{
} // now the code makes sure it gets disposed