在ImageList.Items.Clear()之后调用垃圾收集器

本文关键字:调用 收集器 之后 ImageList Items Clear | 更新日期: 2023-09-27 18:14:05

#上下文:

从PDF页面生成PNG,并通过ImageList 在ListView中显示

#期望行为:

当用户选择要在列表视图中显示的另一个文件时->清除ImageList和ListView项(显而易见(,并删除生成的图像文件。

#问题:

删除时引发异常:";进程无法访问文件"X.png",因为另一个进程正在使用该文件">

previewImageList.Images.Clear();
previewListView.Items.Clear();
// folder containing the generated PNGs, created at runtime
string folderToDelete = Path.Combine(outputFolder, Path.GetFileNameWithoutExtension(selectedSong));
try
{                
  Directory.Delete(folderToDelete, true);  // Image file "X.png" is used by another process
}
catch (Exception)
{}

找到的解决方案:

  • 在删除所述PNG文件之前手动调用垃圾收集器似乎可以做到这一点。

    previewImageList.Images.Clear((;previewListView.Items.Clear((;

    string folderToDelete=Path.Combine(outputFolder,Path.GetFileNameWithoutExtension(selectedSong((;

    尝试{GC.Collect((;GC.WaitForPendingFinalizers((;

    Directory.Delete(folderToDelete, true);
    

    }catch(异常ex({MessageBox.Show(例如Message(;}

但是正如我迄今为止研究的那样,这不是一件好事。除了调用垃圾收集器,我还有其他选择吗?我需要删除PNG的原因是能够用另一个路径的PDF重复使用各自的文件名。。。

我最接近的是这里和这里,但帮不了什么忙。

编辑其他详细信息生成PNG:

  • 我这样使用ImageMagik:

    startInfo=新的ProcessStartInfo((;startInfo.FileName="quot;+实用程序文件夹+";''convert.exe";startInfo.Arguments="quot;+selectedPDF文件.pdf"+"quot"+"-重采样168x140"+Path。Combine(outputFolder,selectedPDFFileShortName(+";。png"+"quot";startInfo.UseShellExecute=false;startInfo.CreateNoWindow=true;startInfo.WindowStyle=处理窗口样式。隐藏;startInfo.RedirectStandardError=true;startInfo.RedirectStandardOutput=true;

    process=process.Start(startInfo(;过程WaitForExit(5000(;//等待时间不超过5秒

    if(process.HasExited({//好}其他{//中止所有操作}

将图像加载到ImageList&列表视图:

void previewSelectedPresentation(string presentationName)
{
  previewImageList.Images.Clear();
  previewListView.Items.Clear();
            
  DirectoryInfo dir = new DirectoryInfo(@"E:''test''" + presentationName);
            
  foreach (FileInfo file in dir.GetFiles())
  {
    try
    {
      this.previewImageList.Images.Add(Image.FromFile(file.FullName));
    }
    catch
    {
      Console.WriteLine("This is not an image file");
    }
  }
  for (int j = 0; j < this.previewImageList.Images.Count; j++)
  {
    ListViewItem item = new ListViewItem();
    item.ImageIndex = j;
    item.Text = (j + 1).ToString();                
    this.previewListView.Items.Add(item);
  }
}

在ImageList.Items.Clear()之后调用垃圾收集器

问题已解决。根据上面的Hans Passant,

这在很久以前就出了问题。我忘记处理我之后的图像将它们添加到ImageList中。

因此,以下是添加到ImageList中的正确方法(请参阅原始问题进行比较(-通过注释表示的更改:

void previewSelectedPresentation(string presentationName)
{
  previewImageList.Images.Clear();
  previewListView.Items.Clear();
  DirectoryInfo dir = new DirectoryInfo(@"E:''test''" + presentationName);
  foreach (FileInfo file in dir.GetFiles())
  {
    try
    {  
       // these three lines have changed
       Image slideImage = Image.FromFile(file.FullName);  // change 1
       this.previewImageList.Images.Add(slideImage);      // change 2
       slideImage.Dispose();                              // change 3
    }
    catch
    {
      Console.WriteLine("This is not an image file");
    }
  }
  for (int j = 0; j < this.previewImageList.Images.Count; j++)
  {
    ListViewItem item = new ListViewItem();
    item.ImageIndex = j;
    item.Text = (j + 1).ToString();                
    this.previewListView.Items.Add(item);
  }          
}

现在可以在不调用GC的情况下进行清理。谢谢你帮我自己解决这个问题!此外,这里还有一个有用的答案。