System.Drawing.dll中的C#内存不足异常

System.Drawing.dll中的C#内存不足异常,c#,exception,timer,listbox,out-of-memory,C#,Exception,Timer,Listbox,Out Of Memory,我用c#制作了一个幻灯片,代码运行良好,没有给我任何错误,但当我在30-60秒后点击播放按钮时,它停止并给我内存不足异常System.Drawing.dll。有解决这个问题的办法吗?多谢各位 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Diagnostics; using System.Drawing; using Syst

我用c#制作了一个幻灯片,代码运行良好,没有给我任何错误,但当我在30-60秒后点击播放按钮时,它停止并给我内存不足异常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();
    }

}
使用系统;
使用System.Collections.Generic;
使用系统组件模型;
使用系统数据;
使用系统诊断;
使用系统图;
使用System.IO;
使用System.Linq;
使用系统文本;
使用系统线程;
使用System.Threading.Tasks;
使用System.Windows.Forms;
名称空间幻灯片放映
{
公共部分类幻灯片放映:表单
{
公共幻灯片()
{
初始化组件();
如果(计时器间隔<200)
{
计时器。间隔=100;
}
否则如果(计时器间隔>8000)
{
定时器间隔=600;
}
否则{
时间间隔=2000;
}
}
字符串目录;
私有void btnImagesSelection\u单击(对象发送方,事件参数e)
{
FolderBrowserDialog ask=新建FolderBrowserDialog();
if(ask.ShowDialog()==DialogResult.OK)
{
字符串folName=ask.SelectedPath;
foreach(Directory.GetFiles(folName))中的字符串fullfol)
{
dir=fullfol.Substring(0,fullfol.LastIndexOf(“\\”));
picImages.Image=Image.FromFile(fullfol);
添加(Path.GetFileName(fullfol));
lblNum.Text=lstmages.Items.Count.ToString()+“/”+lstmages.Items.Count.ToString();
}
}
}
私有void lstImages\u SelectedIndexChanged(对象发送方,事件参数e)
{
字符串curitem=lstImages.SelectedItem.ToString();
picImages.Image=Image.FromFile(dir+“\\”+curitem);
lblNum.Text=(lstmages.SelectedIndex+1.ToString()+“/”+lstmages.Items.Count.ToString();
}
布尔翻转=真;
int i=0;
私有void btnPlay_单击(对象发送方,事件参数e)
{ 
timer.Start();
计时器。间隔=1000;
timer.Tick+=新事件处理程序(timetick);
}
void timetick(对象发送方,事件参数e)
{
int numitems=lstmages.Items.Count;
如果(翻转)
如果(i

}

Image
类将图像数据作为非托管资源保存。
垃圾收集器无法卸载这些资源,当您调用
Dispose
方法或通过时,内存将被释放。定稿太慢,无法处理大量图像,因此每次加载新图像时,都应该处理旧图像

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

如果(picImages.Image!=null)picImages.Image.Dispose(),则在分配新图像之前,您不会处理加载的任何图像@TaW您不应在分配新图像之前处理图像。它会引起错误不,不会的。除非您使用
picImages.Refresh()强制执行它。但这不会发生在这里,所以它是安全的。我们确实应该这样做。但是,由于在这两行代码之间没有运行代码,因此“难以获取”似乎仍然有点戏剧性;-)在调用oldImage.Dispose()之后,还可以尝试使用GC.Collect()和GC.WaitForPendingFinalizers()。虽然它们是一个非常昂贵的操作,但我有时会使用OutOfMemoryExceptions,即使调用Image.Dispose()方法。