gpt4 book ai didi

c# - 为什么在某些系统上PictureBox.Load锁定图像?

转载 作者:太空狗 更新时间:2023-10-29 22:59:13 24 4
gpt4 key购买 nike

(如果您不想阅读整个故事,请查看问题底部的编辑内容。)

你好,

我是Stackoverflow的新手。不要误会我的意思,我经常使用它。但是直到现在,我还没有发布过任何东西。这是因为我没有新鲜的话要说,而且我的英语也不太好。第一件事(可能已经改变),后者没有改变。

我最近在客户的Windows 7系统上遇到问题。我通过ClickOnce交付了C#.Net 4.0 Windows Forms应用程序。基本上,它是一个创建位图文件并将其显示给用户的应用程序。如果位图在创建之前存在,则现有文件将首先被删除。之后,将创建新文件并由PictureBox加载。

客户的系统发生了以下情况:启动应用程序后,第一个创建成功-第二个创建成功,而第二个创建都不成功。无法删除该文件,因为某些进程阻止了该文件。这个过程就是应用程序本身。

System.IO.IOException: The process cannot access the file “filename” because it is being used by another process.



好吧,当然这并不稀奇。问题是我在多个系统上测试了该应用程序。没有人显示此异常。直到现在,我仍然看不到代码错误。

因此,我在客户的系统上看得更近一点:我能找到的唯一区别是,他们更改了用户文件夹,以便它们不在Windows分区上,而是在另一个分区上(C:\Users- > D:\Users)。我在互联网上搜索了一条说明,并在一个测试系统上做了同样的事情。令我惊讶的是,我在其上运行应用程序时遇到了同样的异常。

这样,我可以更改代码,以便不再发生异常。但是我不明白为什么。因此,也许我的代码出了点问题,而该错误只是在这种特殊情况下才显现出来。也许代码还可以,原因就在别处。我只是希望您能为我提供帮助。

因此,这是我放在一起的一些代码,它们显示出相同的行为。我在窗体上使用了3个按钮,一个OpenFileDialog和一个PictureBox。首先要做的是选择一个图像文件。通过按下其余两个按钮之一,它将被复制到应用程序的主文件夹中。复制后,将由PictureBox显示它。顺便说一句,它是ClickOnce应用程序还是“正常”应用程序似乎并不重要。
String m_FileName;

private void btnChooseFile_Click(object sender, EventArgs e) {
if(openFileDialog1.ShowDialog() == System.Windows.Forms.DialogResult.OK) { // If file was chosen, set file name for later use and activate buttons.
m_FileName = "Test" + Path.GetExtension(openFileDialog1.FileName);
}
}

private void button1_Click(object sender, EventArgs e) {

// This is not working.
if(this.pictureBox1.Image != null) {
//Image img = this.pictureBox1.Image; // I was not sure, if maybe the pictureBox somehow prevents the disposing of the image, as long as it's assigned to it.
//this.pictureBox1.ImageLocation = null; // So I set them null, both the image and the image location.
//this.pictureBox1.Image = null;
//img.Dispose(); // Then I disposed the image.

this.pictureBox1.Image.Dispose(); // The short version. It is not working either way.
this.pictureBox1.Image = null;
}
(new FileInfo(openFileDialog1.FileName)).CopyTo(m_FileName, true); // But still this is where the Exception occurs.
this.pictureBox1.Load(m_FileName);
}

private void button2_Click(object sender, EventArgs e) {

//This is working.
if(this.pictureBox1.Image != null) {
//Image img = this.pictureBox1.Image;
//this.pictureBox1.Image = null;
//img.Dispose();

this.pictureBox1.Image.Dispose();
this.pictureBox1.Image = null;
}
(new FileInfo(openFileDialog1.FileName)).CopyTo(m_FileName, true);
pictureBox1.Image = Image.FromFile(m_FileName);
}

现在发生的情况如下:如果我启动该应用程序并单击两次button1,则将获得异常(第二次单击)。如果启动它,然后单击两次button2,则不会。如果我启动该应用程序并先单击button1,然后单击该button2,则将得到异常。因此,Picture.Load-Function会以某种方式阻止文件,即使我将其丢弃也是如此。

在Internet上搜索时,我发现了来自Microsoft的一篇文章: http://support.microsoft.com/kb/309482/en-us。但这并没有引起公牛的注意。

考虑到,这两个版本都可以在我的所有测试机上使用。当我将用户文件夹更改为非Windows分区时,我只是得到了异常(exception)。

这是为什么?所提供版本的区别在哪里?

编辑

好的,由于到目前为止的第一个也是唯一的 react ,在我看来仍然不清楚,实际上会发生什么:如果我将上面的代码放入Windows Forms应用程序中,进行编译并在不同的版本上运行计算机(在工作中,在家中都无所谓)都可以工作-我可以随意使用button1和button2(链接有单击功能的两个按钮)-不会引发异常。如果我在更改用户文件夹的计算机上运行该应用程序,然后第二次单击button1-bam-IOException,则该文件已被进程锁定。只要我不按button1,Button2就可以工作。

第一个答案意味着,我应该锁定每个系统。但是我不会(只要不更改用户文件夹)!我在可以接触到的每台计算机上都对其进行了测试-没有IOException。我建立了一个新系统,只是为了排除对公司系统的某些特殊更改-两个buttonx_Click函数都起作用-也不异常(exception)。我什至在另一台计算机上编译了该程序-行为相同。仅有的三个抛出该异常的系统是具有更改后的用户文件夹的系统。

到目前为止,我还不知道为什么会出现这种行为差异。有人可以帮我吗?

有人吗

最佳答案

是的,这很正常。发生在任何操作系统上,与“用户”文件夹位置无关。 PictureBox.Load()方法旨在用于从文件系统以外的位置加载图像。就像一个网站。这很慢,可以避免在进行下载时卡住UI。

当发现您传递的网址实际上是文件而不是网站名称时,它在内部使用FileStream。在释放PictureBox本身或再次调用Load()方法之前,不会释放此FileStream。这是一个要求,因为Image.FromStream()要求流保持可读性,直到不再使用该图像为止。正是此FileStream锁定了文件。布置PictureBox.Image不足以也布置FileStream,Image对象不知道它正在图片框内显示。

有几种方法可以解决此问题:

  • 使用Image属性代替Load(),从Image.FromFile()分配它。现在,处理镜像还会释放文件上的锁定。如您所见
  • 保留一个虚拟图像,其中可能显示一个“正在加载...”位图。首先加载()它以释放对文件
  • 的锁定
  • 放置PictureBox并重新创建它。
  • 关于c# - 为什么在某些系统上PictureBox.Load锁定图像?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22177458/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com