Serge Vinogradov
Serge Vinogradov

Reputation: 730

files in C# - "file is used by another process"

I have following code:

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

It is supposed to read value "location" from the file and put it to the combo box, which works ok.

I run this script on Form1_Load.

Now, I have another script:

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

This one is supposed to record the choice so that user doesn't need to enter location every time.

What is happening is when I start a program, so the value is already set, then I try to change it (so that theoretically it should overwrite the previous one), but I get an exception, saying that file is already being used by another process.

I do close the file after I used it. I also tried FILE.DISPOSE.

What am I doing wrong?

Upvotes: 2

Views: 304

Answers (5)

Issa Fram
Issa Fram

Reputation: 2634

You never need to call file.Close() or file.Dispose().

Please use a using statement ALWAYS (or mostly) when using a class that implements IDisposable. It will call the Dispose method for you.

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

Upvotes: 0

rsbarro
rsbarro

Reputation: 27339

I think what's happening here is that this code:

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

is causing the SelectedIndexChanged event to be raised on the combobox. When that event is raised, comboBox1_SelectedIndexChanged is called, and that method again tries to access location.txt.

To fix, I would first change the code in askforlocation to something like this:

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

since there's no need to keep the file open for longer than necessary (note that the using block will call the Dispose() method on the StreamReader when it exits, which in turn will call the Close() method). After that, I'd consider coming up with a way to keep the event from being fired when you set the selected index on the combobox (maybe use a flag or unwire/rewire the event handler).

Upvotes: 3

Mamta D
Mamta D

Reputation: 6450

Give this line loc.Close(); before setting the index of the combo box because the event is being raised earlier than you think.

Upvotes: 0

JP Richardson
JP Richardson

Reputation: 39395

It seems that you're changing the index of your combobox, thus writing to the same file before closing it. Call loca.Close() before writing to the file again.

Upvotes: 2

ojlovecd
ojlovecd

Reputation: 4892

comboBox1.SelectedIndex = index; this will fire the event SelectedIndexChanged, so invoke the Close() method right behind ReadToEnd():

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

Upvotes: 1

Related Questions