我编写了一个UI导入工具,它将扫描一堆文件夹,找到其中的所有XML文件,加载它们以对有效性进行第一次基本检查,然后尝试在DB中导入它们(这导致另一个更大的一堆有效性检查来运行)。 当基本检查或导入失败时,应用程序会向用户显示详细的错误消息,因此用户可以打开相应的XML文件并进行编辑。 但是......用户无法保存文件,因为该文件“正由另一个进程使用”。
在那个阶段,我的所有导入器对象早已不复存在,但我认为它们可能尚未被垃圾收集,因此它们保持XML文件的打开句柄。所以我在检查/导入过程之后尝试了GC.Collect(),然后神奇地用户可以编辑和保存XML文件。
我的所有代码都使用XML文件:
XmlReader reader = XmlReader.Create(m_xmlInputFile);
m_XmlDocument = new XmlDocument();
m_XmlDocument.Load(reader);
'reader'是一个局部变量,因此它立即超出范围,m_XmlDocument是一个成员变量,只要导入器对象处于活动状态,它就会存在。导入器对象是另一个函数中的局部变量,所以在完成所有操作后,所有内容都应该在死囚区中结束。看起来在死囚区等待可能还需要一段时间......
在我的情况下并不重要,但出于好奇,我想知道是否有什么我可以做的(除了强制GC)“释放”磁盘上的XML文件,以便用户可以毫无意外地进行编辑。
由于
答案 0 :(得分:1)
XmlReader
实施了IDisposable
,而且你没有阻止你的合同结束。
在适当的时间点击Dispose
,或者(更好)围绕using
块中使用它的代码:
using(XmlReader reader = XmlReader.Create(m_xmlInputFile))
{
m_XmlDocument = new XmlDocument();
m_XmlDocument.Load(reader);
}
如果您曾发现自己强制进行垃圾收集,那么您做错了(达到99.99%以内)。
当引用超出范围时,没有任何神奇的事情发生 - 是的,它引用的对象将成为符合条件的用于垃圾收集(如果这是对象的最后剩余引用),但没有额外的代码将运行。
然而,如果对象持有资源,并且应该尽快清理它,它将实现disposable pattern