C#中的文件 - “文件被另一个进程使用”

时间:2011-10-28 04:59:32

标签: c# .net

我有以下代码:

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!";        
        }

应该从文件读取值“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

我做错了什么?

5 个答案:

答案 0 :(得分: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()方法)。在那之后,我会考虑提出一种方法来防止在组合框上设置选定的索引时触发事件(可能使用标记或取消/重新连接事件处理程序)。

答案 1 :(得分:2)

您似乎正在更改组合框的索引,因此在关闭之前写入同一文件。在再次写入文件之前调用loca.Close()。

答案 2 :(得分: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!";        
        }

答案 3 :(得分:0)

在设置组合框的索引之前给出此行loc.Close();,因为事件的提升时间比您想象的要早。

答案 4 :(得分:0)

您永远不需要调用file.Close()或file.Dispose()。

使用实现IDisposable的类时,请始终(或大多数情况下)使用using语句。它将为您调用Dispose方法。

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