1

我有这个开源库,但在解决问题时遇到了一些麻烦……这个库允许轻松创建 XML 文件来存储应用程序设置。但是我在保存更改时遇到了问题。

我有另一个应用程序,我正在使用这个库,每次应用程序窗口完成调整大小时,我都会调用库的 Save() 方法将窗口大小/位置保存到 XML 文件中。

大多数时候它工作正常,一切都被保存了。不过,偶尔,我会收到一个异常,说该文件正在被另一个进程使用。

我真的需要确保每次调用 Save() 方法时都保存更改,我需要以某种方式处理此异常或防止它发生。

你们有什么建议可以最好地处理这种情况?

Save() 方法的代码如下:

public void Save() {
    // Create a new XML file if there's no root element
    if(xDocument.DocumentElement == null) {
        xDocument = new XmlDocument();
        xDocument.LoadXml("<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n" +
            "<" + XmlRootElement + ">\n</" + XmlRootElement + ">");
    }

    // OMITTED CODE WAS HERE (NOT IMPORTANT FOR THE PROBLEM)

    // Create a new XML writer for the XML file
    XmlWriter xWriter = XmlWriter.Create(XmlFilePath, new XmlWriterSettings() {
        Indent = true,
        IndentChars = "\t"
    });

    // Sort the XML file using the XSL sylesheet and save it
    xslTransform.Transform(xDocument, xWriter);

    // Clear the buffer and close the XML writer stream
    xWriter.Flush();
    xWriter.Close();
}
4

4 回答 4

3

XmlWriter 是 IDisposable。您应该将其包装在 using() 子句中。 http://msdn.microsoft.com/en-us/library/system.xml.xmlwriter.aspx

于 2009-05-11T19:14:17.253 回答
2

我必须结合这里已经给出的答案。

出于多种原因,您的 XmlWriter 应该位于 using 块中。您应该处置它,以便尽快释放您的资源。此外,如果您在与它交互时抛出异常怎么办。该文件不会被正确关闭,至少在终结器启动并释放您的资源之前。

即使使用 using 语句,您也“可能”对文件有争用,需要将 Save 代码放在 lock 语句中。该方法本质上是不可重入的,因为文件是共享资源。如果您没有多个线程,那么在它周围加锁可能会过度杀戮,但您会确保正确控制对文件的访问。

要考虑的另一件事是您可能希望将保存操作移动到后台线程以将文件写出。如果你得到一个大的设置文件,你可能会导致奇怪的 UI 交互,因为每次用户调整大小时你都在等待文件写入,这发生在 UI 线程上。如果你这样做了,你肯定需要锁定对文件资源的访问。

于 2009-05-11T21:38:47.157 回答
1

您也可以尝试使用锁定语句。可能是这些方法相互超越。

于 2009-05-11T19:15:43.600 回答
1

可能是 window-resizing-completed 事件触发得如此之快,以至于调用了 save 函数,在它第一次完成运行之前再次调用。这将导致您描述的错误(使用该文件的另一个进程是......你!)。 尝试用锁包围您的代码,因此

lock(some_shared_object)
{
    //Your code here
}
于 2009-05-11T19:48:29.707 回答