同步 XmlWriter 对文件的访问以防止 IOException 的最佳方法是什么?

发布于 2024-07-11 14:32:04 字数 829 浏览 6 评论 0原文

应用程序中有多个位置对同一文件调用 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;
        }
    }

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

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

残疾 2024-07-18 14:32:04

使用锁可以解决并发问题,从而避免 IOException,但是您必须记住在 SaveToDisk 和 ReadFromDisk 上使用相同的对象(我假设这是读取函数),否则仅在读取时锁定完全没有用。

private static readonly object syncLock = new object();

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

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

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 ...
     }
}
寒江雪… 2024-07-18 14:32:04

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

private static readonly object syncLock = new object();

那么...

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

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

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.

用心笑 2024-07-18 14:32:04

我实际上会使用 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 打开文件以便后续读取不会失败。

I'd actually use a ReaderWriterLock to maximise concurrency. You can allow multiple readers but only one writer at a time.

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

Just make sure to open the file with FileShare.Read so that subsequent reads don't fail.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文