Saving XML stream in C# says that it's being used by another process

Question!

I have this open-source library that I'm having some trouble fixing a problem... This library allows to easily create an XML file to store application settings. But I'm having an issue saving the changes.

I have another application where I'm using this library and every time that application window is done resizing, I call the Save() method of the library to save the window size/position to the XML file.

Most of times it works fine, everything is saved. Once in a while though, I get an exception saying the file is being used by another process.

I really need to make sure that changes are saved every time the Save() method is called, I need to handle this exception somehow or prevent it from happening.

What are you guys suggestions for best handling this situation?

The code for the Save() method is the following:

public void Save() {
    // Create a new XML file if there's no root element
    if(xDocument.DocumentElement == null) {
        xDocument = new XmlDocument();
        xDocument.LoadXml("<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n" +
            "<" + XmlRootElement + ">\n</" + XmlRootElement + ">");
    }

    // OMITTED CODE WAS HERE (NOT IMPORTANT FOR THE PROBLEM)

    // Create a new XML writer for the XML file
    XmlWriter xWriter = XmlWriter.Create(XmlFilePath, new XmlWriterSettings() {
        Indent = true,
        IndentChars = "\t"
    });

    // Sort the XML file using the XSL sylesheet and save it
    xslTransform.Transform(xDocument, xWriter);

    // Clear the buffer and close the XML writer stream
    xWriter.Flush();
    xWriter.Close();
}


Answers

I have to go with a combination of the answers already given here.

Your XmlWriter should be in a using block for several reasons. You should dispose it so that your resources are freed as soon as possible. Also, what if you throw an exception while interacting with it. The file wouldn't be closed properly, at least until the finalizer kicks in and frees your resources.

Even with the using statement, you "might" have contention on the file and need to place the Save code in a lock statement. The method is non-reentrant by nature because the file is a shared resource. Putting a lock around it might be over kill if you don't have multiple threads, but you would ensure that you properly controlled access to the file.

The other thing to consider is that you might want to move the saving operation to a background thread to write the file out. If you get a large settings file you might cause strange UI interactions because you are waiting on the file to write every time the user resizes and this happens on the UI thread. If you did this you would definitely need to lock access to the file resource.



It could be the case that the window-resizing-completed events are firing so quickly, that the save function is being called, the called again before it finishes running the first time. This would result in the error you're describing (the other process using the file is... YOU!). Try surrounding your code with a lock, thusly:

lock(some_shared_object)
{
    //Your code here
}
By : GWLlosa


If they have broken one of following ... it's time to refactor. Hey, guy you are looking for SOLID ... screencasts are here

  • SRP: Single Responsibility Principle, THERE SHOULD NEVER BE MORE THAN ONE REASON FOR A CLASS TO CHANGE

  • OCP: Open Closed Principle, SOFTWARE ENTITIES (CLASSES, MODULES, FUNCTIONS, ETC.) SHOULD BE OPEN FOR EXTENSION BUT CLOSED FOR MODIFICATION

  • LSP: Liskov Substitution Principle, FUNCTIONS THAT USE ... REFERENCES TO BASE CLASSES MUST BE ABLE TO USE OBJECTS OF DERIVED CLASSES WITHOUT KNOWING IT.

  • ISP: Interface Segregation Principle, CLIENTS SHOULD NOT BE FORCED TO DEPEND UPON INTERFACES THAT THEY DO NOT USE

  • DIP: Dependency Inversion Principle,

    A. HIGH LEVEL MODULES SHOULD NOT DEPEND UPON LOW LEVEL MODULES. BOTH SHOULD DEPEND UPON ABSTRACTIONS

    B. ABSTRACTIONS SHOULD NOT DEPEND UPON DETAILS. DETAILS SHOULD DEPEND UPON ABSTRACTIONS

And it's all, have fun :)

By : ruslander


This video can help you solving your question :)
By: admin