(請參閱編輯對這個問題的底部,如果你不想讀故事的全部。)爲什麼PictureBox.Load鎖定圖像上的一些系統?
嗨,
我是新來的StackOverflow。不要誤解我的意思,我經常使用它。但直到現在,我從未真正發佈過一些東西。這是因爲我沒有什麼新東西可以說,而我的英語不太好。第一件事(可能有)改變了,後者沒有改變。
我碰見了客戶的Windows 7系統問題最近相當。我通過ClickOnce發佈了一個C#.Net 4.0 Windows Forms應用程序。基本上,它是創建位圖文件並將其顯示給用戶的應用程序。如果位圖在創建之前存在,則現有文件首先被刪除。之後,新文件由PictureBox創建並加載。
下面的事情發生在客戶的系統:啓動第一個創建成功申請後 - 第二個及以後的人沒有。該文件不能被刪除,因爲某些進程阻止了它。這個過程就是應用程序本身。
System.IO.IOException:進程無法訪問文件「filename」,因爲它正在被另一個進程使用。
嘛,當然是沒有什麼不尋常。事情是我在幾個系統上測試了這個應用程序。沒有人顯示這個例外。直到現在,我無法看到代碼錯誤。
所以我在客戶的系統上看起來更接近一點:我能找到的唯一區別是,他們更改了users文件夾,以使它們不位於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兩次,我將得到異常(第二次單擊)。如果我啓動它並點擊按鈕2兩次,我不會。如果我啓動該應用程序並首先單擊按鈕1,然後在該按鈕2之後,我會得到該異常。因此,Picture.Load-Function以某種方式阻止文件,即使我將其丟棄。
當我在網上搜索時,我發現了一篇來自微軟的文章:http://support.microsoft.com/kb/309482/en-us。但它並沒有打到公牛的眼睛。
考慮到這兩個版本都適用於我的所有測試機器。當我將用戶文件夾更改爲非Windows分區時,我只是遇到了異常情況。
這是爲什麼?所提供版本的區別在哪裏?
編輯
好了,因爲迄今爲止第一個也是唯一的反應,在我看來,它仍然是不明確的,到底發生了什麼:如果我把上面的代碼,把它在Windows窗體應用程序中編譯並在不同的計算機上運行(在工作中,在家中,無所謂)它的工作原理 - button1和button2(使用鏈接到它們的Click-函數)可以像我一樣經常使用像 - 沒有例外拋出。如果我在計算機上運行該應用程序,並在其中更改了用戶文件夾,然後第二次單擊button1 - bam - IOException,文件被進程鎖定。只要不按下按鈕1,Button2就會工作。
第一個答案意味着我應該鎖定每個系統。但我不(只要我不更改用戶文件夾)!我在每一臺可以得到我的手的計算機上測試它 - 無IOException。我建立了一個新系統,只是爲了排除我公司系統的一些特殊更改 - buttonx_Click函數都能正常工作 - 也不例外。我甚至在另一臺電腦上編譯了程序 - 同樣的行爲。只有三個引發異常的系統是具有更改的用戶文件夾的系統。
到目前爲止,我還沒有線索,爲什麼會出現這種行爲差異。有人能幫助我嗎?
有人嗎?
雖然我明白了答案,它佔只爲觀察到的行爲的一半。如果事實上它是鎖定圖像的文件流,不應該是所有系統上的行爲都一樣嗎?爲什麼,如果我「癱瘓」系統,我只能得到鎖定行爲? 如果我自己執行FileStream-Version並且不處理FileStream,則會在我所有的測試系統上得到異常(如預期的那樣!)。所以必須有所不同。 – user3379589
我不相信這是特定於某些機器的。您剛收到一位發現該問題的客戶的錯誤報告,並尋找解釋說明爲什麼只有該客戶纔看到它。他們都這樣做,但很容易避免,因爲兩次加載完全相同的圖像並不常見。只需在您自己的機器上重新制作它。 –
上述應用程序(不是上述構造)僅處理單個位圖文件,它創建它自己並向用戶顯示。沒有人能改變它的名字,它是固定的。所以用戶對結果沒有任何影響。 上面的例子是使用較少代碼重現兩種效果的最簡單方法。只要文件格式相同,您可以使用不同的文件名。結果是同名的「Test.fileformat」。但那不是重點。 當我使用上面的示例時,如果您說的話適用,那麼兩個版本都可以在我公司的每個系統上工作,但Version1不應該。 – user3379589