Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 尽管使用了image.Dispose,但图像查看器内存不足_C#_.net_Winforms_Picturebox - Fatal编程技术网

C# 尽管使用了image.Dispose,但图像查看器内存不足

C# 尽管使用了image.Dispose,但图像查看器内存不足,c#,.net,winforms,picturebox,C#,.net,Winforms,Picturebox,当我在用C#编码的图像查看器中添加下一个和上一个导航选项时,当我按“下一步”大约20次时,Visual Studio会告诉我该过程内存不足。它可以在任何包含多个文件夹的文件夹中执行此操作,即使它们的图像文件大小都很小 我得到: System.Drawing.dll中发生“System.OutOfMemoryException”类型的未处理异常。其他信息:内存不足 这是我正在使用的代码 private void next_Click(object sender, EventArgs e) {

当我在用C#编码的图像查看器中添加下一个和上一个导航选项时,当我按“下一步”大约20次时,Visual Studio会告诉我该过程内存不足。它可以在任何包含多个文件夹的文件夹中执行此操作,即使它们的图像文件大小都很小

我得到:

System.Drawing.dll中发生“System.OutOfMemoryException”类型的未处理异常。其他信息:内存不足

这是我正在使用的代码

private void next_Click(object sender, EventArgs e)
{
    string[] foldernm = Directory.GetFiles(Path.GetDirectoryName(lfoto_file.FileName));
    _pictureIndex++;
    if (_pictureIndex >= foldernm.Length)
    {
        _pictureIndex = 0;
    }
    ibread_img.Image.Dispose();
    ibread_img.Image = Image.FromFile(foldernm[_pictureIndex]);
}

现在您可以看到,我有
ibread_img.Image.Dispose()那里,因为我搜索过这个,其他人说要使用它,但它不起作用,我仍然遇到同样的问题,一个断点确认代码正在运行,所以我不明白为什么它仍然没有内存。我正在循环浏览的图像不是很大。我已经尝试了我能找到的一切,包括清空先前加载的映像,手动调用垃圾收集器,但似乎什么都不起作用。我并不擅长C#所以代码中可能有一个可怕的错误或缺陷,但我不知道如何解决这个问题?

感谢LarsTech和Proputix指出我的错误。此新代码现在运行良好:

private void next_Click(object sender, EventArgs e)
    {
        var filteredFiles = Directory.EnumerateFiles(Path.GetDirectoryName(lfoto_file.FileName))
            .Where(file => file.ToLower().EndsWith("jpg") || file.ToLower().EndsWith("png") || file.ToLower().EndsWith("gif") || file.ToLower().EndsWith("bmp") || file.ToLower().EndsWith("tiff") || file.ToLower().EndsWith("ico"))
            .ToList();
        _pictureIndex++;
        if (_pictureIndex >= filteredFiles.Count)
        {
            _pictureIndex = 0;
        }
        ibread_img.Image.Dispose();
        ibread_img.Image = Image.FromFile(filteredFiles[_pictureIndex]);
        init();
    }

我只需要筛选出正确的格式。

您可以做一些事情来改进查看器。首先,每次都要重新创建图像文件列表;你每次都在加载它们,只是为了访问下一个,你不必创建一个图像来显示它

// class level vars
int picIndex = 0;
IEnumerable<string> files;
int filesCount;
string picPath;
static string[] imgExts = {".png", ".jpg",".gif"};
然后是显示所需图像的方法:

private void ShowImage(int Index)
{ 
    // create image list if needed (once)
    if (files == null)
    { 
        files = new DirectoryInfo(picPath).EnumerateFiles().
            Where(q => imgExts.Contains(q.Extension.ToLowerInvariant())).
            Select( z => z.FullName);

        filesCount = files.Count();
    }

    string thisFile = files.ElementAt(Index);

    // no need to dispose an image if you never create one          
    pb2.ImageLocation = thisFile;
    lblImgName.Text = Path.GetFileName(thisFile);
}
而不是每次(在两个位置)创建一个文件列表,每次只创建一次,而不是加载所有文件的列表,这样就可以根据需要将其保留为
IEnumerable
。它还适用于
FileInfo
,不区分大小写,主要是为了说明一种不同的方式,允许您根据创建日期对它们进行排序(OrderBy)

最后,给定完整路径和文件名,您可以使用
.ImageLocation
属性,避免创建和处理
图像


最主要的是尽量减少重复代码的数量,这样您就可以。“下一个”和“上一个”的代码将几乎相同。

您是否确实拥有有效的图像文件?引发异常后是否仍在绘制图像?如果是这样,这可能是重复的:由于您没有指定搜索模式/过滤器,您可能正在尝试加载非图像文件。问题是它没有检查下一个文件是否为图像,正如LarsTech和Proputinix所说,我犯了一个愚蠢的错误,我完全忘记并忽略了它,非常感谢,对于所有类型的问题,Di都有抛出
OutOfMemoryException
的坏习惯,其中许多问题与内存不足无关。我发现这通常意味着图像文件已损坏,或者是GDI无法读取的格式。谢谢你,我将尝试你所说的,我确实希望尽可能优化我的代码
private void ShowImage(int Index)
{ 
    // create image list if needed (once)
    if (files == null)
    { 
        files = new DirectoryInfo(picPath).EnumerateFiles().
            Where(q => imgExts.Contains(q.Extension.ToLowerInvariant())).
            Select( z => z.FullName);

        filesCount = files.Count();
    }

    string thisFile = files.ElementAt(Index);

    // no need to dispose an image if you never create one          
    pb2.ImageLocation = thisFile;
    lblImgName.Text = Path.GetFileName(thisFile);
}