2015-11-01 52 views
0

我做了一個使用c#的幻燈片,代碼運行良好,並沒有給我任何錯誤,但是當我在30-60秒後點擊播放按鈕時,它停止並讓我走出內存異常System.Drawing.dll。任何想法來解決這個問題?謝謝C#內存不足在System.Drawing.dll中的異常

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Diagnostics; 
using System.Drawing; 
using System.IO; 
using System.Linq; 
using System.Text; 
using System.Threading; 
using System.Threading.Tasks; 
using System.Windows.Forms; 
namespace Slide_Show 
{ 
    public partial class SlideShow : Form 
{ 
    public SlideShow() 
    { 
     InitializeComponent(); 
     if (timer.Interval < 200) 
     { 
      timer.Interval = 100; 
     } 
     else if(timer.Interval > 8000) 
     { 
      timer.Interval = 600; 
     } 
     else{ 
      timer.Interval = 2000; 
     } 
    } 
    string dir; 
    private void btnImagesSelection_Click(object sender, EventArgs e) 
     { 
     FolderBrowserDialog asked = new FolderBrowserDialog(); 
     if (asked.ShowDialog() == DialogResult.OK) 
     { 
      string folName = asked.SelectedPath; 
      foreach (string fullfol in Directory.GetFiles(folName)) 
      { 
       dir = fullfol.Substring(0, fullfol.LastIndexOf(("\\"))); 
       picImages.Image = Image.FromFile(fullfol); 
       lstImages.Items.Add(Path.GetFileName(fullfol)); 
       lblNum.Text = lstImages.Items.Count.ToString() + "/" + lstImages.Items.Count.ToString(); 
      } 
     } 

    } 

    private void lstImages_SelectedIndexChanged(object sender, EventArgs e) 
    { 
     string curitem = lstImages.SelectedItem.ToString(); 
     picImages.Image = Image.FromFile(dir+"\\"+curitem); 
     lblNum.Text = (lstImages.SelectedIndex+1).ToString() + "/" + lstImages.Items.Count.ToString(); 
    } 
    bool flip = true; 
    int i = 0; 
    private void btnPlay_Click(object sender, EventArgs e) 
    { 
     timer.Start(); 
     timer.Interval = 1000; 
     timer.Tick += new EventHandler(timetick); 
    } 
    void timetick(object sender, EventArgs e) 
    { 

     int numitems = lstImages.Items.Count; 
     if (flip) 
      if (i < numitems) 
      { 
       try 
       { 
        lblNum.Text = (i + 1) + "/" + numitems; 
        picImages.Image = Image.FromFile(dir + "\\" + lstImages.Items[i].ToString()); 
        i += 1; 
       } 
       catch 
       { 
        timer.Stop(); 
       } 
      } 
      else if (i == numitems) 
      { 
       i = 0; 
      } 
     flip = !flip; 
    } 

    private void btnSlow_Click(object sender, EventArgs e) 
    { 
     try 
     { 
      timer.Interval *= 2; 
     } 
     catch 
     { 
      timer.Interval = 6000; 
     } 
    } 

    private void btnFast_Click(object sender, EventArgs e) 
    { 
     try 
     { 
      timer.Interval /= 2; 
     } 
     catch 
     { 
      timer.Interval = 100; 
     } 

    } 

    private void btnStop_Click(object sender, EventArgs e) 
    { 
     timer.Stop(); 
    } 

} 

}

+1

你的arent的任何圖像處置加載 – Plutonix

+0

分配,如果一個新的插入'之前(picImages.Image!= NULL)picImages.Image.Dispose();' – TaW

+0

@TaW你不應該處理的分配新圖像之前的圖像。它可能會導致錯誤 –

回答

2

Image類保存圖像數據作爲非託管資源。這些資源不能通過Garbage Collector卸載,並且當您撥打Dispose方法或finalization時,內存將被釋放。 Finalization對於處理大量圖像來說太慢,所以每次加載新圖像時都應該丟棄舊圖像。

private void LoadNewImage(string path) 
{ 
    var oldImage = picImages.Image; 
    picImages.Image = Image.FromFile(dir+"\\"+curitem); 
    if(oldImage!= null) 
    { 
     oldImage.Dispose(); 
    } 
} 
+0

你是對的,現在我明白它是如何工作的,謝謝你:) – AHA27

+0

你也可以嘗試在調用oldImage.Dispose()之後使用GC.Collect()和GC.WaitForPendingFinalizers()。儘管它們是相當昂貴的操作,但即使我調用Image.Dispose()方法,我也有時會使用OutOfMemoryExceptions。 – eMko