图片被用于由另一个进程(layoutpanel)(picture is used by anothe

2019-10-28 13:15发布

所以我填充图像的浮动布局面板,使用此代码:

    private void FillPanel(string sql)
    {
        panel.Controls.Clear();

        SQLiteConnection dbConnect = new SQLiteConnection("Data Source=" + dbFullPath + ";Version=3;");
        dbConnect.Open();

        SQLiteCommand runQuery = new SQLiteCommand(sql, dbConnect);
        SQLiteDataReader reader = runQuery.ExecuteReader();

        while (reader.Read())
        {              
            PictureBox pB = new PictureBox();
            pB.Image = Image.FromFile(reader["imgPath"].ToString());
            pB.Size = new Size(100, 100);
            pB.SizeMode = PictureBoxSizeMode.StretchImage;
            pB.Padding = new Padding();
            pB.Margin = new Padding(5,5,5,5);
            pB.Name = reader["name"].ToString();
            toolTip_Main.SetToolTip(pB, pB.Name);

            pB.DoubleClick += img_DoubleClick;

            panel.Controls.Add(pB);
        }
        dbConnect.Close();

    }

如果我尝试删除源的图片后,我得到的errormessage的。

“image.png被另一个过程”

要删除我用下面的代码的图片:

     private void Delete()
    {
            foreach (Control x in panel.Controls)
            {
                if (x is PictureBox)
                {
                    PictureBox pb = x as PictureBox;
                    string name = pb.Name;

                    DirectoryInfo pF = new DirectoryInfo(pictureFolder);
                    foreach (FileInfo file in pF.GetFiles())
                    {
                        if(file.Name == name+".png")
                        {
                            pb.InitialImage = null;
                            pb.Dispose();
                            file.Delete();
                            break;
                        }
                    }
                }
            }
     }

如果我不填充图像的面板,我能够删除它们。 我只是不知道我接下来会做些什么,以“initialimage = NULL”&.dispose到盖茨摆脱面板内的图像。

但似乎他们是重影的地方。

在这个任何想法?

Answer 1:

基本规则时要记住打开图像有这些:

  • Image从文件创建的对象将所述图像对象的生命周期过程中锁定文件 ,防止文件被重写或删除,直到该图像布置。
  • Image从流创建的对象将需要流保持打开以供图像对象的整个生命周期 。 不像文件,没有什么积极执行这项,但流关闭后,当保存,克隆或以其他方式操纵的图像会给出错误。

(如果你想知道, Image.FromFile(String filename)是实际上只是一个包装new Bitmap(String filename)构造函数。我个人建议不要使用Image.FromFile ,因为它失去了更精确的Bitmap返回对象的类型。)


至于你的问题,似乎在配置PictureBox不配置实际图像。 这或许可以明确地配置来解决pb.Image第一:

Image img = pb.Image;
// Needs to happen in this order so the UI will never try to paint the disposed image
pb.Image = null;
if (img != null)
    img.Dispose();
file.Delete();
break;

需要注意的是配置的实际图像框可能导致的问题; 你应该从其父控制首先除去它,所以它不再显示在UI上,否则你的表单将开始抛出“对象设置”异常,因为它试图绘制控件之一是无效的。


周围的锁定问题的另一种方法是从磁盘中读取位图时,使用创建一个新的位图出来的new Bitmap(Image image)构造函数,然后从配置文件初始化位图对象。 要做到这一点,最好的办法是用using指令,就像这样:

using (Bitmap im = new Bitmap(reader["imgPath"].ToString()))
    pB.Image = new Bitmap(im);

作为一项规则,你应该经常清理你啦创建图像对象。 请注意,这实际上描绘的图像的新32bppARGB图像上,从而失去该图像的任何原始格式。 虽然你的情况我想这没有多大意义的,因为它只是用于显示反正在UI上。 (请注意,如果你需要一个完整的1:图像的1数据副本没有任何链接到流或文件,有办法做到这一点,但他们更高级一些的是 。)



文章来源: picture is used by another process (layoutpanel)