如何最好地同步XmlWriter对文件的访问,以防止IOExceptions?

4

应用程序中有多个地方在同一个文件上调用XmlWriter.Create,所有这些地方都通过以下函数访问。当一个调用时另一个仍在写入时,会出现IOException异常。最好的方法是锁定或同步访问权限是什么?

以下是正在使用的函数:

        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;
        }
    }

更新:看起来问题不仅仅是调用此函数时出现的,而是因为另一个线程在此函数写入文件时正在读取该文件。最好的方法是如何进行锁定,以便我们在读取文件时不尝试写入文件?

3个回答

4
使用锁可以解决并发问题,从而避免IOException的出现。但是你必须记得在SaveToDisk和ReadFromDisk(我假设这是读取函数)中使用同一个对象,否则仅在读取时加锁是完全无用的。
private static readonly object syncLock = new object();

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

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

3

一个静态锁可以快速简单地完成工作:

private static readonly object syncLock = new object();

then...

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

您还可以使用[MethodImpl(MethodImplOptions.Synchronized)] (用于接受实例作为参数的静态方法,例如扩展方法),但显式锁更加通用。


1

我会使用ReaderWriterLock来最大化并发性。您可以允许多个读取器,但一次只能有一个写入器。

private ReaderWriterLock myLock = new ReaderWriterLock();

public void SaveToDisk()
{
     myLock.AcquireWriterLock();
     try
     {
          ... write code ...
     } 
     finally
     {
          myLock.ReleaseWriterLock();
     }
}

public void ReadFromDisk()
{
     myLock.AcquireReaderLock();
     try
     {
          ... read code ...
     } 
     finally
     {
          myLock.ReleaseReaderLock();
     }
}

请确保使用 FileShare.Read 打开文件,以便后续读取不会失败。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接