2014-05-08 38 views
0

我在處理資源時遇到了一些問題。爲什麼我嘗試在try塊的finally語句中釋放資源時出現此錯誤?

我HEVE驗證碼:

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對象,以這樣的方式

bitmap = new Bitmap(WIDTH, HEIGHT); 

嘗試塊。

在塊結束時,我有finaly在至極我嘗試配置資源:

finally 
{ 
    bitmap.Dispose(); 
} 

但這裏給我下面的錯誤信息:

錯誤2使用未分配的局部變量'位圖'

爲什麼?我能做些什麼來解決它? (我不希望使用使用 statment)

TNX

+2

*爲什麼*你不是t使用'using'語句嗎?這就是它的設計目的。 –

+2

你不應該放棄'位圖'!你將它返回給調用者,這是調用者的責任來處理它。 –

回答

8

爲什麼?

因爲bitmap根據語言規範的規則沒有明確分配。試想一下,如果Bitmap構造函數拋出異常。你會處置什麼?

我能做些什麼來解決它? (我不希望使用使用statment的)

那麼你可以使用

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聲明...

+1

除了OP從函數返回位圖以外,所以不應該丟棄它。 –

+0

@ T.J.Crowder:是的,我剛剛注意到了這一點,並在答案的最後添加了一些內容。 –

0

因爲你沒有指定什麼位圖,你不能處理它! 即使分配「空」將解決此問題。 雖然它不像你想要的那樣「乾淨」。 在聲明上分配null,然後在處理它之前檢查它是否爲空,會更好。 看吧!如果你想返回對象。

0

bitmap.Dispose調用起,bitmap可能沒有值(如果new Bitmap引發異常)。

因爲在你返回位圖給調用者正常情況下,我可能做到這一點:

Bitmap bitmap = null; 

...讓bitmap肯定有一個值,然後添加一個null檢查您的finally條款:

finally 
{ 
    if (bitmap != null) { 
     bitmap.Dispose(); 
    } 
} 

...和洗牌周圍返回時:

Bitmap rv = bitmap; 
bitmap = null; 
return rv; 
0

你不應該使用處置所有的位圖,因爲它是由函數返回:

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(); 
    } 
} 
+0

可能想要在錯誤處理中處理,如果* new *之外的其他*出現錯誤。如果稍後發生異常,上面不會調用Dispose。 –

相關問題