We have a website application which acts as a form designer.
The form data is stored in XML file. Each form has it’s own xml file.
When i edit a form, i basically recreate the XML file.
public void Save(Guid form_Id, IEnumerable<FormData> formData)
{
XDocument doc = new XDocument();
XElement formsDataElement = new XElement("FormsData");
doc.Add(formsDataElement);
foreach (FormData data in formData)
{
formsDataElement.Add(new XElement("FormData",
new XAttribute("Id", data.Id)
new XAttribute("Name", data.Name)
// other attributes
));
}
doc.Save(formXMLFilePath);
}
This works good, but i want to make sure that two users won’t update at the same time the XML file. I want to lock it somehow.
How can i individually lock the save process for each file?
I could lock the Save function like below, but this will lock all the users, even if they save a different XML file.
private static readonly object _lock = new object();
public void Save(Guid form_Id, IEnumerable<FormData> formData)
{
lock(_lock)
{
XDocument doc = new XDocument();
foreach (FormData data in formData)
{
// Code
}
doc.Save(formXMLFilePath);
}
}
Try something like this:
This uses a
FileStreamand we supply aFileSharemode. In our case we are exclusively locking the file so that only we can write to it.However, this simply means that subsequent writes will fail as there is a lock.
To get around this problem I tend to have a queue and a separate thread who’s only job is to process the queue and write to the file system.
However another solution is to simply try and access the file, and if that fails wait a little bit then try again. This would let you do something akin to
lockwhere it waits until it can access and then proceeds: