为什么我有这个错误,当我试图处置一个资源在一个尝试块的最后语句

本文关键字:一个 资源 语句 最后 错误 为什么 | 更新日期: 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();
    }
}