C# XmlDoc抛出进程无法随时访问文件?
我有以下基于数据契约编写XML文件的代码C# XmlDoc抛出进程无法随时访问文件?,c#,.net,xml,filestream,xmldocument,C#,.net,Xml,Filestream,Xmldocument,我有以下基于数据契约编写XML文件的代码 public static void LogDataContractToFile(string XMLStringToLog, string filePathAndName) { //String documentPath = string.Empty; String xmlObject = string.Empty; FileInfo fileinfo;
public static void LogDataContractToFile(string XMLStringToLog, string filePathAndName)
{
//String documentPath = string.Empty;
String xmlObject = string.Empty;
FileInfo fileinfo;
XmlDocumentFragment xmlDocumentFragment;
XmlTextWriter xmlWriter;
XmlDocument xmlDocument = null;
lock (LogDataContractToFileLock)
{
filePathAndName = filePathAndName.ToLower();
while (_workingWithFile.Contains(filePathAndName))
Thread.Sleep(1000);
_workingWithFile.Add(filePathAndName.ToLower());
try
{
#region Create XMLFile
fileinfo = new FileInfo(filePathAndName);
if (!fileinfo.Exists)
{
DirectoryInfo info = new DirectoryInfo(fileinfo.DirectoryName);
if (info.Exists == false)
info.Create();
using (xmlWriter = new XmlTextWriter(filePathAndName, System.Text.Encoding.UTF8))
{
xmlWriter.Formatting = Formatting.Indented;
xmlWriter.WriteStartDocument();
xmlWriter.WriteStartElement("root");
xmlWriter.WriteStartElement("objects");
xmlWriter.WriteEndElement();
xmlWriter.WriteEndElement();
xmlWriter.WriteEndDocument();
xmlWriter.Close();
}
}
else
{
//Se så att filen är 50 MB eller mindre
while (fileinfo.Length > 52428800)
{
xmlDocument = new XmlDocument();
xmlDocument.Load(filePathAndName);
xmlDocument.RemoveChild(xmlDocument.LastChild);
xmlDocument.Save(filePathAndName);
xmlDocument = null;
}
}
#endregion
xmlObject = XMLStringToLog;
//Open document
xmlDocument = new XmlDocument();
xmlDocument.Load(filePathAndName);
//Create a new fragment in current document
xmlDocumentFragment = xmlDocument.CreateDocumentFragment();
xmlDocumentFragment.InnerXml = xmlObject;
//Add new fragment after the first child
xmlDocument.DocumentElement.InsertBefore(xmlDocumentFragment, xmlDocument.DocumentElement.FirstChild);
xmlDocument.Save(filePathAndName);
xmlDocument = null;
}
finally
{
_workingWithFile.Remove(filePathAndName.ToLower());
}
}
}
问题是,有时我会遇到进程无法访问文件的异常情况
?XmlDocument没有任何dispose,因此我无法使用。如何妥善处理
请注意,我被困在.NET 4.0上。要安全地检查元素并添加它,如果它不存在,您应该使用:
private readonly ConcurrentDictionary\u workingWithFile=new ConcurrentDictionary();
公共静态void LogDataContractToFile(字符串XMLStringToLog、字符串filePathAndName)
{
...
锁(LogDataContractToFileLock)
{
...
而(!\u使用file.TryAdd(filePathAndName,true))工作时
{
睡眠(1000);
}
...
尝试
{
...
}
最后
{
//也许在这里检查结果。
布尔结果;
_使用file.TryRemove(文件路径和名称,输出结果);
}
}
}
无论使用什么\u文件都是因为它看起来不安全。两个线程可能会看到它不包含相同的文件,并且都添加了该文件。您的应用程序意外地尝试从多个线程访问同一文件两次。您需要使用线程同步机制来防范这种情况。谢谢,我正在考虑这个问题,所以添加了一个锁。这不会锁定特定的文件(我不认为我需要它)。锁定特定文件会很好,但从我读到的来看,锁定字符串对象并不好?看起来不错,这是一种锁定,但锁定的是特定的文件名(字符串)。我会试试这个。好的,这是一个现在开始,即时通讯股票在.NET4.0它也是。
private readonly ConcurrentDictionary<string,bool> _workingWithFile = new ConcurrentDictionary<string,bool>();
public static void LogDataContractToFile(string XMLStringToLog, string filePathAndName)
{
...
lock (LogDataContractToFileLock)
{
...
while(!_workingWithFile.TryAdd(filePathAndName, true))
{
Thread.Sleep(1000);
}
...
try
{
...
}
finally
{
//Perhaps check the result here.
bool result;
_workingWithFile.TryRemove(filePathAndName, out result);
}
}
}