views:

307

answers:

2

There are multiple places in an application which call XmlWriter.Create on the same file, all accessed through the following function. When one calls while another is still writing, I get an IOException. What's the best way to lock or synchronize access?

Here's the function that's being used:

        public void SaveToDisk()
    {
        try
        {
            XmlWriterSettings settings = new XmlWriterSettings();
            settings.Indent = true;
            using (XmlWriter writer = XmlWriter.Create(SaveFileAbsolutePath, settings))
            {
                XamlWriter.Save(this, writer);
                writer.Close();
            }

        }
        catch (Exception ex)
        {
            // Log the error
            System.Diagnostics.Debug.WriteLine(ex.Message);

            // Rethrow so we know about the error
            throw;
        }
    }

UPDATE: It looks like the problem isn't just from calls to this function, but because another thread is reading the file while this function is writing to is. What's the best way to lock so we don't try to write to the file while it's being read?

+2  A: 

A static lock should do the job quickly and simply:

private static readonly object syncLock = new object();

then...

public void SaveToDisk()
{
    lock(syncLock)
    {
        ...your code...
    }
}

You can also use [MethodImpl(MethodImplOptions.Synchronized)] (on a static method that accepts the instance as an argument - for example, an extension method), but an explicit lock is more versatile.

Marc Gravell
+2  A: 

Using a lock can solve your concurrency problem and thus avoid the IOException, but you must remember to use the same object either on SaveToDisk and ReadFromDisk (i assume this is the reading function), otherwise it's totally useless to lock only when you read.

private static readonly object syncLock = new object();

public void SaveToDisk()
{
     lock(syncLock)
     {
          ... write code ...
     }
}

public void ReadFromDisk()
{
     lock(syncLock)
     {
          ... read code ...
     }
}
Stefano Driussi