Saving XML stream in C # says it is being used by another process
I have this open source library, I'm having trouble troubleshooting the problem ... This library makes it easy to create an XML file to store application settings. But I have a problem saving changes.
I have another application where I am using this library and every time I resize the application window I call the Save () method of the library to save the window size / position in an XML file.
Many times it works fine, everything is saved. From time to time I get an exception saying that the file is in use by another process.
I really need to make sure changes are saved every time the Save () method is called, I need to somehow handle this exception or prevent it.
What do you guys want to best handle this situation?
The Save () method code is as follows:
public void Save() {
// Create a new XML file if there 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();
}
a source to share
It could be that the events that completed the window change are fired so quickly that the save function gets called, called again before it finishes running the first time. This will result in the error you describe (another process using the file ... YOU!). Try to surround your code with a lock, like this :
lock(some_shared_object)
{
//Your code here
}
a source to share
The XmlWriter is IDisposable. You have to wrap it in a use () clause. http://msdn.microsoft.com/en-us/library/system.xml.xmlwriter.aspx
a source to share
I need to go with a combination of the answers already given here.
Your XmlWriter needs to be in a use block for several reasons. You must dispose of it so that your resources are freed up as soon as possible. Also, what to do if you throw an exception while interacting with it. The file will not close properly, at least not until the finalizer starts working and frees up your resources.
Even with a using statement, you might have a conflict with the file and need to put the save code in a lock statement. This method is not inherently reentrant because the file is a shared resource. If the lock around it can be killed if you don't have multiple threads, but you have to make sure that you have properly controlled access to the file.
Another thing is that you can move the save operation to a background thread to write the file. If you get a large settings file, you might cause strange user interface interactions because you are waiting for the write file every time the user resizes and this happens on the UI thread. If you have done this, you will definitely need to block access to the file share.
a source to share