读取多个映像文件时内存峰值

本文关键字:内存 文件 映像 读取 | 更新日期: 2023-09-27 18:10:25

我试图使一个文件资源管理器和一个问题,我一直被卡住是试图修复内存尖峰,当我从图像加载多个缩略图发生。这是我认为它所在的部分(这都被封装在后台worker中):

static string[] imageType = new string[] { "jpeg", "jpg", "png", "bmp" };
List<string> filesList = new List<string>();
foreach (FileInfo file in fileList)
    filesList.Add(file.FullName);
string[] files = filesList.ToArray();
NumericComparer nc = new NumericComparer();
Array.Sort(files, nc);
foreach (string file in files)
{
    Application.OpenForms["MDC_Explorer"].Invoke(new MethodInvoker(() =>
    {
        Application.DoEvents();
    }));
    Panel d = new Panel();
    d.Size = new Size(parent.Width / 5 - 10, 100);//Image Height: 70px
    d.Location = new Point(left, top);
    d.Tag = file;
    d.MouseEnter += new EventHandler(item_MouseEnter);
    d.MouseLeave += new EventHandler(item_MouseLeave);
    d.BackgroundImageLayout = ImageLayout.Stretch;
    Label l = new Label();
    FileInfo fileInfo = new FileInfo(file);
    l.Text = Path.GetFileNameWithoutExtension(fileInfo.FullName);
    l.Size = new Size(d.Width, 25);
    l.Location = new Point(0, 75);
    l.TextAlign = ContentAlignment.TopCenter;
    l.ForeColor = Color.FromArgb(255, 90, 90, 90);
    l.Font = new Font(parent.Font.FontFamily, 10, FontStyle.Regular);
    l.BackColor = Color.Transparent;
    l.MouseEnter += new EventHandler(item_MouseEnter);
    l.MouseLeave += new EventHandler(item_MouseLeave);
    l.MouseClick += new MouseEventHandler(item_MouseClick);
    d.Controls.Add(l);
    PictureBox pb = new PictureBox();
    string path = file;
    if (Path.GetExtension(file).Replace(".", "") == "lnk")
    {
        IWshRuntimeLibrary.WshShell shell = new IWshRuntimeLibrary.WshShell();
        IWshRuntimeLibrary.IWshShortcut link = (IWshRuntimeLibrary.IWshShortcut)shell.CreateShortcut(file);
        path = link.TargetPath;
    }
    if (!File.Exists(path) && path.Contains("Program Files (x86)"))
        path = path.Replace("Program Files (x86)", "Program Files");
    Bitmap bmp = Path.GetExtension(path).Replace(".", "") == "exe" ? Icon.ExtractAssociatedIcon(path).ToBitmap() : (imageType.Contains(Path.GetExtension(path).Replace(".", "")) ? new Bitmap(Image.FromStream(new MemoryStream(File.ReadAllBytes(path))), new Size(d.Width - 20, 80)) : new Bitmap(GetLargeIconForExtension(Path.GetExtension(path)).ToBitmap()));
            bigThumbnail.Add(bmp);
    int fp = (parent.Width / 4) * 3 - 50;
    smallThumbnail.Add(new Bitmap(bmp, new Size((fp / 5), 80)));
    pb.BackgroundImage = bmp;
    pb.BackgroundImageLayout = ImageLayout.Center;
    pb.Size = new Size(d.Width - 20, 80);
    pb.BackColor = Color.Transparent;
    pb.Location = new Point(10, 10);
    pb.MouseEnter += new EventHandler(item_MouseEnter);
    pb.MouseLeave += new EventHandler(item_MouseLeave);
    pb.MouseClick += new MouseEventHandler(item_MouseClick);
    d.Controls.Add(pb);
    if (left + (d.Width * 2) + 5 >= parent.Width)
    {
        top += d.Height + 5;
        left = 5;
    }
    else
        left += d.Width + 5;
    Application.OpenForms["MDC_Explorer"].Invoke(new MethodInvoker(() =>
    {
        parent.Controls.Add(d);
    }));
}

对不起,如果我提供了太多的代码,但我相信错误是它得到缩略图,并把它变成一个位图,但我不确定如何降低内存使用。

读取多个映像文件时内存峰值

您正在创建图像和位图而不丢弃它们,因此直到垃圾收集器销毁这些bmp之前,它们都在内存中。

同样,在某些情况下,您正在读取内存中的所有图像文件,将其加载到流中,然后将其传递给image。FromStream,比Image.FromFile.

要好得多。

代替:

Bitmap bmp = Path.GetExtension(path).Replace(".", "") == "exe" ?     
Icon.ExtractAssociatedIcon(path).ToBitmap() : 
(imageType.Contains(Path.GetExtension(path).Replace(".", "")) ? new 
Bitmap(Image.FromStream(new MemoryStream(File.ReadAllBytes(path))), 
new Size(d.Width - 20, 80)) : new Bitmap(GetLargeIconForExtension(Path.GetExtension(path))
.ToBitmap()));

这样做:

        Bitmap bmp;
        string ext = Path.GetExtension(path);
        if (ext == ".exe")
        {
            Icon ico = Icon.ExtractAssociatedIcon(path);
            bmp = ico.ToBitmap();
            ico.Dispose();
        }
        else
        {
            if (imageType.Contains(ext.Replace(".", "")))
            {
                Image img = Image.FromFile(path);
                bmp = new Bitmap(img, new Size(d.Width - 20, 80));
                img.Dispose();
            }
            else
            {
                Icon ico = GetLargeIconForExtension(ext);
                bmp = ico.ToBitmap();
                ico.Dispose();
            }
        }