C# 在C中保存XML流表示它';正在被另一个进程使用
我有一个开源库,我在修复一个问题时遇到了一些问题。。。此库允许轻松创建XML文件来存储应用程序设置。但是我在保存更改时遇到了一个问题 我有另一个应用程序正在使用这个库,每次调整应用程序窗口的大小时,我都调用库的Save()方法将窗口大小/位置保存到XML文件中 大多数时候,它工作正常,一切都保存了下来。不过,偶尔我会收到一个异常,说该文件正被另一个进程使用 我确实需要确保每次调用Save()方法时都保存更改,我需要以某种方式处理此异常或防止其发生 你们有什么建议可以最好地处理这种情况 Save()方法的代码如下所示:C# 在C中保存XML流表示它';正在被另一个进程使用,c#,xml,file,process,save,C#,Xml,File,Process,Save,我有一个开源库,我在修复一个问题时遇到了一些问题。。。此库允许轻松创建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();
}
public void Save(){
//如果没有根元素,则创建新的XML文件
if(xDocument.DocumentElement==null){
xDocument=新的XmlDocument();
xDocument.LoadXml(“\n”+
“\n”);
}
//此处省略了代码(对问题不重要)
//为XML文件创建新的XML编写器
XmlWriter xWriter=XmlWriter.Create(XmlFilePath,新的XmlWriterSettings(){
缩进=真,
IndentChars=“\t”
});
//使用XSL sylesheet对XML文件排序并保存它
Transform(xDocument,xWriter);
//清除缓冲区并关闭XML编写器流
xWriter.Flush();
xWriter.Close();
}
XmlWriter是可识别的。应该将其包装在using()子句中。
XmlWriter是可识别的。应该将其包装在using()子句中。
您也可以尝试使用lock语句。可能是这些方法相互溢出。您也可以尝试使用lock语句。可能是这些方法相互溢出。可能是窗口大小调整完成的事件触发得太快,导致正在调用save函数,在第一次运行完成之前再次调用。这将导致您描述的错误(使用该文件的另一个进程是…您!):
可能的情况是,调整窗口大小的已完成事件触发得太快,以至于正在调用save函数,在第一次运行完成之前再次调用save函数。这将导致您描述的错误(使用该文件的另一个进程是…您!):
我必须结合这里已经给出的答案 您的XmlWriter应该处于使用块中,原因有几个。您应该处理它,以便尽快释放资源。另外,如果在与异常交互时抛出异常会怎么样。至少在终结器启动并释放您的资源之前,文件不会被正确关闭 即使使用using语句,您“可能”对文件有争用,并且需要将Save代码放在lock语句中。该方法本质上是不可重入的,因为该文件是共享资源。如果没有多个线程,在其周围加上锁可能会导致死机,但可以确保正确控制对该文件的访问
要考虑的另一件事是,您可能希望将保存操作移到后台线程来写入文件。如果您得到一个大的设置文件,您可能会导致奇怪的UI交互,因为每次用户调整大小时,您都在等待该文件写入,而这发生在UI线程上。如果您这样做了,您肯定需要锁定对文件资源的访问。
我必须结合这里已经给出的答案 您的XmlWriter应该处于使用块中,原因有几个。您应该处理它,以便尽快释放资源。另外,如果在与异常交互时抛出异常会怎么样。至少在终结器启动并释放您的资源之前,文件不会被正确关闭 即使使用using语句,您“可能”对文件有争用,并且需要将Save代码放在lock语句中。该方法本质上是不可重入的,因为该文件是共享资源。如果没有多个线程,在其周围加上锁可能会导致死机,但可以确保正确控制对该文件的访问要考虑的另一件事是,您可能希望将保存操作移到后台线程来写入文件。如果您得到一个大的设置文件,您可能会导致奇怪的UI交互,因为每次用户调整大小时,您都在等待该文件写入,而这发生在UI线程上。如果您这样做了,您肯定需要锁定对文件资源的访问。
99.44%确定它是using()语句。您不需要锁。我不确定使用()是否是根本问题,因为他调用了XmlWriter.Close()。我没有看到catch块吞噬异常,所以我看不出他会错过任何从那里飞出的异常,这是Close()不会被调用的唯一方法。99.44%的确定率是using()语句。您不需要锁。我不确定使用()是否是根本问题,因为他调用了XmlWriter.Close()。我没有看到捕获块吞咽异常,所以我看不出他会错过任何从那里飞出的异常,这是Close()不会被调用的唯一方法。你能解释一下为什么你几乎确定我应该使用using()而不是lock()?到目前为止,我理解锁的原因,我认为它是有意义的,而不是使用…哎呀;我可能说错话了。using()子句对于实现IDisposable的类是必需的。锁定可能也是必要的,这取决于调整大小逻辑是否允许交错或并发调整大小事件lock(some_shared_object)
{
//Your code here
}