为什么我有这个错误,当我试图处置一个资源在一个尝试块的最后语句
本文关键字:一个 资源 语句 最后 错误 为什么 | 更新日期: 2023-09-27 18:02:30
处理资源时遇到问题。
我有这样的代码:
class ChartHelper
{
//public static System.Drawing.Image GetPdfChart(int percentage)
public static System.Drawing.Bitmap GetPdfChart(int percentage)
{
if (percentage == 0)
{
return null;
}
int WIDTH = 130;
int HEIGHT = 10;
//using (Bitmap bitmap = new Bitmap(WIDTH, HEIGHT))
//{
Bitmap bitmap;
try {
bitmap = new Bitmap(WIDTH, HEIGHT);
using (Graphics graphics = Graphics.FromImage(bitmap))
{
using (LinearGradientBrush brush = new LinearGradientBrush(new Rectangle(0, 0, WIDTH, HEIGHT), Color.LightGreen, Color.Red, LinearGradientMode.Horizontal))
{
graphics.FillRectangle(brush, new Rectangle(0, 0, WIDTH, HEIGHT));
using (Bitmap target = new Bitmap(WIDTH * percentage / 100, HEIGHT))
{
Rectangle cropped = new Rectangle(0, 0, WIDTH, HEIGHT);
using (Graphics g = Graphics.FromImage(target))
{
g.DrawImage(bitmap, new Rectangle(0, 0, cropped.Width, cropped.Height), cropped, GraphicsUnit.Pixel);
//g.Save();
//String filename = Path.GetTempFileName() + ".png";
//target.Save(filename);
//return filename;
return bitmap;
}
}
}
}
}
finally
{
bitmap.Dispose();
}
}
}
如你所见,一开始我创建了一个位图对象,如下所示:bitmap = new Bitmap(WIDTH, HEIGHT);
放入try块。
在块的末尾,我有最后,我试图在其中释放资源:
finally
{
bitmap.Dispose();
}
但是这里它给了我以下错误信息:
错误2使用未赋值的局部变量bitmap
为什么?我怎么做才能解决这个问题?(我不想使用using语句)
Tnx
为什么?
因为根据语言规范的规则,bitmap
没有被明确地赋值。想象一下,如果Bitmap
构造函数抛出一个异常。你会处理什么?
我能做些什么来解决它?(我不想使用using语句)
你可以使用:
Bitmap bitmap = null;
try
{
bitmap = ...;
// Code using bitmap
}
finally
{
if (bitmap != null)
{
bitmap.Dispose();
}
}
然而,我强烈建议您使用using
语句。这就是它的设计目的,也是惯用的方法。
Bitmap bitmap = null;
bool success = false;
try
{
bitmap = ...;
// Code using bitmap
...
success = true;
return bitmap;
}
finally
{
if (bitmap != null && !success)
{
bitmap.Dispose();
}
}
在这一点上,当然你做有一个很好的理由不使用using
语句…
因为你没有给bitmap赋值,所以你不能处理它!即使赋值"null"也能解决这个问题。虽然它不像你想要的那么"干净"。在声明时赋值null,然后在处理它之前检查它是否为null,这样会更好。小心!如果你想返回对象
对于bitmap.Dispose
调用,bitmap
可能没有值(如果new Bitmap
抛出异常)。
由于在正常情况下你是将位图返回给调用者,我可能会这样做:
Bitmap bitmap = null;
…因此,bitmap
确实有一个值,然后在finally
子句中添加null
检查:
finally
{
if (bitmap != null) {
bitmap.Dispose();
}
}
…并在返回时随意洗牌:
Bitmap rv = bitmap;
bitmap = null;
return rv;
您根本不应该在位图上使用Dispose,因为它是由函数返回的:
public static System.Drawing.Bitmap GetPdfChart(int percentage)
{
if (percentage == 0) return null;
int WIDTH = 130;
int HEIGHT = 10;
Bitmap bitmap = new Bitmap(WIDTH, HEIGHT);
using (Graphics graphics = Graphics.FromImage(bitmap))
{
using (LinearGradientBrush brush = new LinearGradientBrush(new Rectangle(0, 0, WIDTH, HEIGHT), Color.LightGreen, Color.Red, LinearGradientMode.Horizontal))
{
graphics.FillRectangle(brush, new Rectangle(0, 0, WIDTH, HEIGHT));
using (Bitmap target = new Bitmap(WIDTH * percentage / 100, HEIGHT))
{
Rectangle cropped = new Rectangle(0, 0, WIDTH, HEIGHT);
using (Graphics graphicsTarget = Graphics.FromImage(target))
{
graphicsTarget .DrawImage(bitmap, new Rectangle(0, 0, cropped.Width, cropped.Height), cropped, GraphicsUnit.Pixel);
return bitmap; // IT IS RETURNED HERE, SO DO NOT DISPOSE
// should'nt this be target anyway?
}
}
}
}
}
像这样使用函数来确保Dispose正确执行:
using(var bmp = GetPdfChart(somePercentage))
{
// code goes here.
}
但是如果你真的需要确保,在错误的情况下,位图被正确处置
public static System.Drawing.Bitmap GetPdfChart(int percentage)
{
if (percentage == 0) return null;
int WIDTH = 130;
int HEIGHT = 10;
Bitmap bitmap = null;
bool functionReturned = false;
try
{
bitmap = new Bitmap(WIDTH, HEIGHT);
using (Graphics graphics = Graphics.FromImage(bitmap))
{
using (LinearGradientBrush brush = new LinearGradientBrush(new Rectangle(0, 0, WIDTH, HEIGHT), Color.LightGreen, Color.Red, LinearGradientMode.Horizontal))
{
graphics.FillRectangle(brush, new Rectangle(0, 0, WIDTH, HEIGHT));
using (Bitmap target = new Bitmap(WIDTH * percentage / 100, HEIGHT))
{
Rectangle cropped = new Rectangle(0, 0, WIDTH, HEIGHT);
using (Graphics graphicsTarget = Graphics.FromImage(target))
{
graphicsTarget .DrawImage(bitmap, new Rectangle(0, 0, cropped.Width, cropped.Height), cropped, GraphicsUnit.Pixel);
functionReturned = true;
return bitmap; // IT IS RETURNED HERE, SO DO NOT DISPOSE
// should'nt this be target anyway?
}
}
}
}
}
finally
{
if(!functionReturned && bitmap != null) bitmap.Dispose();
}
}