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

更新:看起来问题不仅来自对该函数的调用,还因为另一个线程正在读取该文件,而该函数正在写入。什么是最好的锁定方式,这样我们就不会在读取文件时尝试写入文件?

4

3 回答 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 ...
     }
}
于 2009-01-14T16:29:41.960 回答
3

静态锁应该快速简单地完成这项工作:

private static readonly object syncLock = new object();

然后...

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

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

于 2009-01-14T08:08:39.147 回答
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打开文件,以便后续读取不会失败。

于 2011-02-14T13:35:07.013 回答