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

本文关键字:文件 进程 另一个 | 更新日期: 2023-09-27 18:12:33

我有以下代码:

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

我做错了什么?

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

我认为这里发生的是这个代码:

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

导致在组合框上引发CCD_ 2事件。当该事件被引发时,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块在退出时将调用StreamReader上的Dispose()方法,而CCD_8又将调用CCD-9方法(。之后,当您在组合框上设置所选索引时,我会考虑想出一种方法来防止事件被触发(可能会使用标志或解开/重新连接事件处理程序(。

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

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

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

您永远不需要调用文件。Close((或文件。Dispose((。

当使用实现IDisposable的类时,请使用using语句ALWAYS(或大部分(。它将为您调用Dispose方法。

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