Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/310.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/image/5.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# 图片被另一个进程使用(layoutpanel)_C#_Image_Dispose_Flowlayoutpanel_System.io.file - Fatal编程技术网

C# 图片被另一个进程使用(layoutpanel)

C# 图片被另一个进程使用(layoutpanel),c#,image,dispose,flowlayoutpanel,system.io.file,C#,Image,Dispose,Flowlayoutpanel,System.io.file,因此,我用图像填充浮动布局面板,代码如下: private void FillPanel(string sql) { panel.Controls.Clear(); SQLiteConnection dbConnect = new SQLiteConnection("Data Source=" + dbFullPath + ";Version=3;"); dbConnect.Open(); SQLiteComma

因此,我用图像填充浮动布局面板,代码如下:

    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();

    }
如果我稍后尝试删除源图片,我会收到一条错误消息

“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旁边我还能做些什么来清除面板中的图像

但他们似乎在某处鬼影


有什么想法吗?

打开图像时要记住的基本规则如下:

  • 从文件创建的
    图像
    对象,在图像被释放之前防止文件被覆盖或删除
  • 从流创建的
    图像
    对象。与文件不同的是,没有任何活动强制执行此操作,但在关闭流后,图像在保存、克隆或以其他方式操作时会出现错误
(如果您想知道,
Image.FromFile(字符串文件名)
实际上只是
新位图(字符串文件名)
构造函数的包装器。我个人建议不要使用
Image.FromFile
,因为它会丢失返回对象的更精确的
位图类型。)


至于您的问题,处理
图片盒
似乎不会处理实际图像。这可能可以通过先显式处理
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上,否则您的窗体将开始抛出“object disposed”异常,因为它尝试绘制的某个控件无效


解决锁定问题的另一种方法是从磁盘读取位图,使用
new bitmap(Image)
构造函数从中创建一个新位图,然后处理从文件初始化的位图对象。最好的方法是使用指令
,如下所示:

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

通常,您应该始终清理创建的图像对象。请注意,这实际上是在一个32bppARGB的新图像上绘制图像,从而丢失图像的任何原始格式。虽然在你的情况下,我想这并不重要,因为它只是为了显示在用户界面上。(注意,如果您确实需要完整的1:1图像数据克隆,而不需要指向流或文件的任何链接,则有多种方法可以做到这一点。)

打开图像时要记住的基本规则如下:

  • 从文件创建的
    图像
    对象,在图像被释放之前防止文件被覆盖或删除
  • 从流创建的
    图像
    对象。与文件不同的是,没有任何活动强制执行此操作,但在关闭流后,图像在保存、克隆或以其他方式操作时会出现错误
(如果您想知道,
Image.FromFile(字符串文件名)
实际上只是
新位图(字符串文件名)
构造函数的包装器。我个人建议不要使用
Image.FromFile
,因为它会丢失返回对象的更精确的
位图类型。)


至于您的问题,处理
图片盒
似乎不会处理实际图像。这可能可以通过先显式处理
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上,否则您的窗体将开始抛出“object disposed”异常,因为它尝试绘制的某个控件无效


解决锁定问题的另一种方法是从磁盘读取位图,使用
new bitmap(Image)
构造函数从中创建一个新位图,然后处理从文件初始化的位图对象。最好的方法是使用指令
,如下所示:

using (Bitmap im = new Bitmap(reader["imgPath"].ToString()))
    pB.Image = new Bitmap(im);
通常,您应该始终清理创建的图像对象。请注意,这实际上是在一个32bppARGB的新图像上绘制图像,从而丢失图像的任何原始格式。虽然在你的情况下,我想这并不重要,因为它只是为了显示在用户界面上。(注意,如果您确实需要一个完整的1:1图像数据克隆,而不需要指向流或文件的任何链接,可以通过多种方法来实现,但是。)