Concurrent Deserialization and Preventing File Locks
Posted
Monday, June 26, 2006 11:29 AM
by
mhodnick
I recently maintained an ASP .Net application where Xml Serialization was used
to read and persist configuration data during page requests. When site traffic
increased, users encountered System.IO.IOExceptions with the
message "The process cannot access the file "c:\SomeFolder\SomeFile.xml"
because it is being used by another process. The exception was not always
encountered 100% of the time. The problem could be easily reproduced by opening
two browser windows, opening the page in each browser, and quickly refreshing
each browser side by side.
I was able to narrow down the problem to a method in a class where
deserialization takes place on each page request. The following code was used:
XmlSerializer serializer = new XmlSerializer(typeof(Foo));
TextReader reader = new StreamReader(serializedFooPath);
myFoo = (Foo)serializer.Deserialize(reader);
reader.Close();
Basically the TextReader locks the file until it is done using
it. You can easily avoid locking a file by changing how it is
accessed. Simply introduce a FileStream object that can control
how the file is accessed rather than allowing the TextReader to
control it for you. The FileStream object can accomplish this by
using the FileShare.Read enumeration value:
XmlSerializer serializer = new XmlSerializer(typeof(Foo));
FileStream fs = new FileStream(serializedFooPath, FileMode.Open, FileAccess.Read, FileShare.Read);
TextReader reader = new StreamReader(fs);
myFoo = (Foo)serializer.Deserialize(reader);
reader.Close();
fs.Close();
According to MSDN, any request to open the file will fail until the file is
closed if FileShare.Read is not specified [1].
Making this change eliminated the problem and the IOException no longer
occurred. It was an easy quick fix - perhaps a better deserialization strategy would come in handy but this fix was able to fix the bug quickly. Thanks to Jake for
helping out by supplying the MSDN reference.
[1] Refer to
http://msdn2.microsoft.com/en-us/library/system.io.fileshare.aspx for
full documentation of the FileShare enumeration and
http://msdn2.microsoft.com/en-us/library/system.io.filestream.aspx for
full documentation of the FileStream class.