views:

52

answers:

1

I have a list box that when an item is selected or deselected I want to save the changes to an xml file (so it is always up-to-date on the file and the user does not need a "save" button).

While testing I occasionally am hitting this IOException:

The process cannot access the file 'C:\MyPath\MyFile.xml' because it is being used by another process.

Here is my XML Serialization code:

// Save an object out to the disk
public static void SerializeObject<T>(this T toSerialize, String filename)
{
    XmlSerializer xmlSerializer = new XmlSerializer(toSerialize.GetType());
    TextWriter textWriter = new StreamWriter(filename);

    xmlSerializer.Serialize(textWriter, toSerialize);
}

// Load an object from the disk
private static T DeserialzeObject<T>(String filename) where T : class
{
    XmlSerializer xmlSerializer = new XmlSerializer(typeof(T));

    try
    {
        TextReader textReader = new StreamReader(filename);
        return (T)xmlSerializer.Deserialize(textReader);
    }
    catch (FileNotFoundException)
    { }

    return null;
}

And here is how it is called:

// Save off the list because the visibility has changed
public void WorkItemColumnTypeOnVisibleChanged(int fieldID, Visibility visibility)
{
    ColumnFields.SerializeObject(ColumnFields.GetSerializeFilename());
}

The deserialize is the one that is giving the error:

WorkItemColumnTypes savedVersion = DeserialzeObject<WorkItemColumnTypes>(result.GetSerializeFilename());

Is there a way to optimize my connections to the file so that I am not tripping over myself?

+4  A: 

Perhaps you need to call Close on the TextWriter objects in your serialization and deserialization methods? Or alternatively use the using construct to force disposal at the end of the block.

Example:

// Save an object out to the disk
public static void SerializeObject<T>(this T toSerialize, String filename)
{
    XmlSerializer xmlSerializer = new XmlSerializer(toSerialize.GetType());
    using(TextWriter textWriter = new StreamWriter(filename))
    {

        xmlSerializer.Serialize(textWriter, toSerialize);
    }
}

// Load an object from the disk
private static T DeserialzeObject<T>(String filename) where T : class
{
    XmlSerializer xmlSerializer = new XmlSerializer(typeof(T));

    try
    {
        using(TextReader textReader = new StreamReader(filename))
        {
            return (T)xmlSerializer.Deserialize(textReader);
        }
    }
    catch (FileNotFoundException)
    { }

    return null;
}
Aviad P.
The call to close fixed it. Thanks!
Vaccano
The using way is safer in case the serialization or deserialization itself raises an exception. You could handle that by putting the close in a finally clause, but that's exactly what using does for you.
Aviad P.