2011-10-28 35 views
2

我有以下代碼:文件在C#中 - 「文件是由另一個進程使用」

private void askforlocation() 
     { 
      if (File.Exists("location.txt")) 
      { 
       System.IO.StreamReader loc = new System.IO.StreamReader("location.txt"); 
       string loca = loc.ReadToEnd(); 
       if (loca != "") 
       { 
        int index = comboBox1.FindString(loca); 
        comboBox1.SelectedIndex = index; 
       } 
       else 
       { 
        label6.Text = "Please select the location!"; 
       } 
       loc.Close(); 
      } 
      else label6.Text = "Please select the location!";   
     } 

它應該從文件中讀取值「位置」,並把它放到組合框,其中工程確定。

我在Form1_Load上運行這個腳本。

現在,我有另一個腳本:

private void comboBox1_SelectedIndexChanged(object sender, EventArgs e) 
{ 
    string value = comboBox1.SelectedItem.ToString(); 
    System.IO.File.WriteAllText("location.txt", value); 
} 

這一個應該記錄的選擇,使用戶無需每次都輸入位置。

發生了什麼是當我啓動一個程序,所以價值已經設置,然後我試圖改變它(所以理論上它應該覆蓋前一個),但我得到一個異常,說該文件已經被另一個進程使用。

我在使用它之後關閉文件。我也試過FILE.DISPOSE

我在做什麼錯?

回答

3

我覺得這裏發生了什麼是此代碼:

if (loca != "") 
{ 
    int index = comboBox1.FindString(loca); 
    comboBox1.SelectedIndex = index; 
} 

是造成SelectedIndexChanged事件的組合框得到提升。當發生該事件時,調用comboBox1_SelectedIndexChanged,並且該方法再次嘗試訪問location.txt

要解決,我會先在askforlocation修改代碼,這樣的事情:

if (File.Exists("location.txt")) 
{ 
    var loca = string.Emtpy; 
    using(var loc = new System.IO.StreamReader("location.txt")) 
    { 
     loca = loc.ReadToEnd(); 
    } 
    .... 
} 

,因爲沒有必要保持文件打開超過所需的時間(注意:using塊將調用Dispose()方法在StreamReader退出時,這反過來會調用Close()方法)。在那之後,我會考慮想出一種方法,當您在組合框中設置選定的索引時(可能使用標誌或取消接線/重新連接事件處理程序),可以防止事件被觸發。

+0

重要的是要指出任何人閱讀這個答案,在「使用」塊中包裝文件讀取隱式調用Close()方法。 –

+0

好點,我更新了我的答案。謝謝! – rsbarro

1

comboBox1.SelectedIndex = index; 這將觸發該事件的SelectedIndexChanged,所以調用右後方ReadToEnd的()的Close()方法:

private void askforlocation() 
     { 
      if (File.Exists("location.txt")) 
      { 
       System.IO.StreamReader loc = new System.IO.StreamReader("location.txt"); 
       string loca = loc.ReadToEnd(); 
       loc.Close();//move that code to here 
       if (loca != "") 
       { 
        int index = comboBox1.FindString(loca); 
        comboBox1.SelectedIndex = index; 
       } 
       else 
       { 
        label6.Text = "Please select the location!"; 
       } 
       //loc.Close(); 
      } 
      else label6.Text = "Please select the location!";   
     } 
2

看來你改變你的組合框的索引,從而寫入同一個文件關閉之前。在再次寫入文件之前調用loca.Close()。

0

在設置組合框的索引之前,先設置此行loc.Close();,因爲事件提前發生得比您想象的要早。

0

你永遠不需要調用file.Close()或file.Dispose()。

當使用實現IDisposable的類時,請始終使用using語句(或大部分)。它會爲你調用Dispose方法。

using(System.IO.StreamReader loc = new System.IO.StreamReader("location.txt")) 
{ 
    string loca = loc.ReadToEnd(); 
} 
相關問題