C# 为什么在尝试在try块的finally station中处理资源时会出现此错误?
我在处理资源时遇到一些问题 我有以下代码:C# 为什么在尝试在try块的finally station中处理资源时会出现此错误?,c#,.net,C#,.net,我在处理资源时遇到一些问题 我有以下代码: class ChartHelper { //public static System.Drawing.Image GetPdfChart(int percentage) public static System.Drawing.Bitmap GetPdfChart(int percentage) { if (percentage == 0)
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);
进入尝试块
在块的末尾,我有一个最后的,其中我尝试处理资源:
finally
{
bitmap.Dispose();
}
但在这里,它给了我以下错误消息:
错误2使用未分配的局部变量“位图”
为什么??我能做些什么来解决它?(我不想使用using语句)
Tnx
为什么?
因为根据语言规范的规则,bitmap
没有明确指定。想象一下,如果位图
构造函数抛出异常。你会怎么处理
我能做些什么来解决它?(我不想使用using语句)
你可以使用:
但是,我强烈建议您对此使用using
语句。这就是它的设计目的,也是惯用的方法
作为一个稍微独立的问题,您将从块的中间返回位图,但您正在处理它。是否确实要返回对已处理位图的引用?你希望打电话的人能用它做什么?您可能需要考虑仅在故障时处理位图。e、 g
Bitmap bitmap = null;
bool success = false;
try
{
bitmap = ...;
// Code using bitmap
...
success = true;
return bitmap;
}
finally
{
if (bitmap != null && !success)
{
bitmap.Dispose();
}
}
在这一点上,您当然有一个很好的理由不使用
using
语句…因为您没有为位图分配任何内容,所以无法处理它!
即使指定“null”也可以解决这个问题。
虽然它不像你想要的那么“干净”。
在声明中指定null,然后在处理它之前检查它是否为null,这样会更好。
小心!如果要返回对象。从
位图.Dispose
调用开始,位图
可能没有值(如果新建位图
引发异常)
因为在正常情况下,您将位图返回给调用者,我可能会这样做:
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?
}
}
}
}
}
使用如下函数确保正确执行处置:
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();
}
}
为什么不想使用
using
语句?这就是它的设计目的。你根本不应该处理位图
!您正在将它返回给调用者,调用者有责任处理它。除了OP正在从函数返回位图,因此根本不应该处理它。@t.J.Crowder:是,我刚刚注意到了这一点,并在答案的末尾添加了一些内容。如果新位图出现问题,可能希望在错误处理中进行处理。如果以后发生异常,上述操作将不会调用Dispose
。
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();
}
}