I’m building a generic xml repository that uses a datacontractserializer to serialize/deserialize the files and I’m unsure as how to ensure that the files cannot be altered when they are being read.
My code to read all files is like this:
public IQueryable<T> All<T>() where T : class, new()
{
List<T> instances = new List<T>();
DirectoryInfo datadirectory = new DirectoryInfo(this.storageLocation);
if (datadirectory.Exists)
{
foreach (FileInfo datafile in datadirectory.GetFiles("*.xml", SearchOption.TopDirectoryOnly))
{
lock (this.syncRoot)
{
instances.Add(this.converter.Build<T>(datafile.FullName));
}
}
}
return instances.AsQueryable();
}
Where converter is the serializer and syncRoot is a private object.
What I am unsure of is where to put the lock? Should it be as above or should I be wrapping the DirectoryInfo read?
I’d like to be able to parallelize the reading process using parallel.foreach but early experiments wrapping the DirectoryInfo led to exceptions.
Threading is a bit of a mystery to me so any input would be greatly appreciated.
Thanks in advance.
If your
converter.Buildreads the whole file, then you could lock around theforeachto prevent other threads in your program to write to those files. In order to prevent other processes to write, you need to open the FileStreams with exclusive read access as mentioned by Henk.If you read the files in lazily (deferred execution) when AsQueryable is being executed by some outside code, then you need to lock in the calling code instead.