如何移除文件锁?C#

如何移除文件锁?C#,c#,file,file-io,C#,File,File Io,所以我使用C#并制作了一个注册系统。因此,有一个选项可以添加图片,我会提示用户选择一个文件,然后该文件将复制到目录文件夹,然后重命名为学生的入学编号。以下是浏览按钮的代码: OpenFileDialog openDlg = new OpenFileDialog(); openDlg.Filter = "All JPEG files (*.jpg; *.jpeg)| *.jpg; *.jpeg"; string filter = openDlg.Fi

所以我使用C#并制作了一个注册系统。因此,有一个选项可以添加图片,我会提示用户选择一个文件,然后该文件将复制到目录文件夹,然后重命名为学生的入学编号。以下是浏览按钮的代码:

OpenFileDialog openDlg = new OpenFileDialog();
            openDlg.Filter = "All JPEG files (*.jpg; *.jpeg)| *.jpg; *.jpeg";
            string filter = openDlg.Filter;
            openDlg.Multiselect = false;
            openDlg.Title = "Open a JPG File";
            if (openDlg.ShowDialog() == DialogResult.OK)
            {                
                curFileName = openDlg.SafeFileName;
                string curFilePath = openDlg.FileName;

                openDlg.Dispose();

                string sourcePath = @curFilePath.Remove((curFilePath.Length - curFileName.Length));
                string targetPath = "@";

                mycon.Open();
                string cmdstr = "SELECT imageDirectory from userSettings WHERE ID = 1";
                cmd = new OleDbCommand(cmdstr, mycon);
                dr = cmd.ExecuteReader();
                while (dr.Read())
                {
                    targetPath = (@dr["imageDirectory"].ToString());
                }
                dr.Close();
                mycon.Close();

                string sourceFile = Path.Combine(sourcePath, curFileName);
                string destFile = Path.Combine(targetPath, curFileName);

                File.Copy(sourceFile, destFile, true);

                newname = @destFile.Remove((destFile.Length - curFileName.Length)).ToString() + "\\" + (DateTime.Now.Year + "-" + textBox1.Text+".jpeg");

                if (File.Exists(newname) == true)
                {
                    pictureBox1.Image.Dispose();
                    try
                    {
                        File.Delete(newname);
                    }

                    catch (IOException ex)
                    {
                        MessageBox.Show(ex.ToString());
                        return;
                    }
                }

                File.Move(destFile, newname);

                photoPath = newname;
                pictureBox1.Image = Image.FromFile(photoPath);
问题是:

a、 )我有一个功能,允许用户进入下一步,如果他想在最后一步做一些更改,他可以返回并更新它。这里的问题是,当他更改图片时,我收到一个错误,说明“文件无法访问,因为它正被另一个进程使用”

b、 )当用户已经上载了图片,然后返回主页时,当他决定再次注册时,他将无法上载新图片,并出现一个错误:“无法访问该文件,因为它正被其他进程使用”

这两个错误都指向这里:

`File.Delete(newname);`

我真的不知道该怎么办,伙计们,我从昨晚开始一直在寻找解决方案,我看不到一个解决方案不能让我完全改变整个代码。请提供帮助:(

在托管语言(如C#)中手动使用
.Dispose()
)是一种。您可能会因为尝试手动管理资源而处于无效状态。您可以通过以下两种方式避免此情况:

  • 去掉不需要的
    .Dispose()
    元素(如
    opnDlg.Dispose()
    ),和/或
  • 尝试使用(…){…}语句将需要处理的对象包装到

  • 无论哪种方式,重构代码后,其中不应该有任何
    .Dispose()
    方法调用。您正在使用的对象不需要手动管理,尝试这样做只会导致问题,或者它们绝对需要管理,因此使用(…)
    语句优越得多,因为它保证在退出代码块时释放资源。

    您的代码是正确的,请忽略关于代码气味的说明。处理PictureBox.Image对于避免内存不足异常非常重要

    这个问题是由位图类的一个实现细节引起的。当你打开一个图像文件时,该类会创建一个内存映射文件,将图像的像素数据映射到内存中。这是对大型图像的一个重要优化,它将像素数据保留在分页文件之外。这在15年后的今天已经不再那么重要了在设计GDI+时,现代机器有大量的RAM和磁盘空间

    但是,该内存映射文件会在文件上创建一个锁。这对于防止任何其他进程弄乱文件数据和使文件的映射视图无效非常重要。这就是您看到的,尝试替换或删除文件不再有效。您可以通过创建位图的深度副本来避免它,该副本包含所有的pixel数据存储在内存中,不再使用该文件。如下所示:

    public static Bitmap LoadBitmapNolock(string path) {
        using (var img = Image.FromFile(path)) {
            return new Bitmap(img);
        }
    }
    

    请注意,使用此代码,32位版本的Windows上的大图像内存不足的几率会显著增加。

    我要尝试的第一件事是找到任何可以访问文件并具有
    Dispose
    Close
    方法的对象。我不完全熟悉
    OleDbConnection
    类,但我确实看到这是您在代码中唯一没有明确处理的对象。我如何使用using块?抱歉,我对c#@JohnErnestGuadalupe中的文件管理有点陌生,您可以在这里读到:。本质上,它是这样工作的…
    使用(Foo-bar=new-Foo()){//do stuff-with-bar}
    非常感谢您提供的见解。如果还有其他问题,我将使用此选项并向您进行更新。谢谢!好的,所以在调用File.Copy()、File.Exists()和File.Delete之前,我只在代码中使用此选项,对吗?不,替换您的Image.FromFile()通过调用此帮助程序方法在代码段底部进行调用。它非常有效!!非常感谢!!我不知道该错误只能通过短代码解决!谢谢!!!@Idle-绘制图像时会意外崩溃,并出现“一般错误”。请注意MSDN库警告:“您必须在映像的整个生命周期内保持流的打开状态”。感谢您提供的信息。我从未在使用FromStream时遇到过此问题。您能给出一个容易产生此错误的示例吗?