【发布时间】:2014-03-04 16:26:54
【问题描述】:
(如果您不想阅读整个故事,请参阅问题底部的编辑。)
你好,
我是 stackoverflow 的新手。不要误会我的意思,我经常使用它。但到目前为止,我从未真正发布过任何东西。这是因为我没有新的/有用的东西要说,而且我的英语也不是很好。第一件事(可能)改变了,后者没有。
我最近在客户的 Windows 7 系统上遇到了问题。我通过 ClickOnce 发布了一个 C# .Net 4.0 Windows 窗体应用程序。基本上,它是一个创建位图文件并将其显示给用户的应用程序。如果位图在创建之前存在,则首先删除现有文件。之后,新文件由 PictureBox 创建和加载。
客户系统发生以下事情:启动应用程序后,第一个创建成功 - 第二个和所有后续创建都没有。该文件无法删除,因为某些进程正在阻止它。这个过程就是应用程序本身。
System.IO.IOException:进程无法访问文件“filename”,因为它正被另一个进程使用。
嗯,这当然没什么不寻常的。问题是我在几个系统上测试了该应用程序。没有人显示此异常。直到现在我还看不到代码错误。
所以我仔细查看了客户的系统:我能发现的唯一区别是,他们更改了用户文件夹,因此它们不在 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 两次,我不会。如果我启动应用程序并先单击按钮 1,然后单击按钮 2,我将得到异常。所以,Picture.Load-Function 会以某种方式阻止文件,即使我将其丢弃。
在网上搜索的时候,发现了一篇来自微软的文章:http://support.microsoft.com/kb/309482/en-us。但它并没有击中靶心。
请注意,这两个版本都可以在我所有的测试机器上运行。当我将用户文件夹更改为非 Windows 分区时,我只是得到了异常。
这是为什么呢?所呈现的版本有何不同?
编辑
好的,因为到目前为止的第一个也是唯一一个反应,在我看来,仍然不清楚,真正发生了什么:如果我采用上面的代码,把它放在一个 Windows 窗体应用程序中,编译它并运行它在不同的计算机上(在工作中,在家里,没关系)它可以工作 - 按钮 1 和按钮 2(与它们链接的 Click 功能)可以随心所欲地使用 - 不会抛出异常。如果我在更改用户文件夹的计算机上运行该应用程序,然后第二次单击 button1 - bam - IOException,文件被进程锁定。只要我不按 button1,Button2 就可以工作。
第一个答案暗示,我应该锁定每个系统。但我不会(只要我不更改用户文件夹)!我在每一台我能拿到手的计算机上测试了它——没有 IOException。我建立了一个新系统,只是为了排除对我公司系统的一些特殊更改——两个 buttonx_Click 功能都有效——也不例外。我什至在另一台计算机上编译了程序 - 相同的行为。唯一抛出该异常的三个系统是用户文件夹已更改的系统。
到目前为止,我不知道为什么会出现这种行为差异。有人可以帮助我吗?
有人吗?
【问题讨论】:
标签: c# winforms bitmap picturebox file-locking