c#exception进程无法访问该文件

我得到一个例外:进程无法访问该文件。

这是代码:

if (!Monitor.TryEnter(lockObject)) return; try { watcher.EnableRaisingEvents = false; try { XmlDocument xdoc = new XmlDocument(); xdoc.Load(FileName); xdoc = null; } catch (XmlException xe) { using (StreamWriter w = File.AppendText(FileName)) { Console.WriteLine(xe); w.WriteLine(""); w.WriteLine(""); } } System.Threading.Thread.Sleep(2000); XPathDocument myXPathDoc = new XPathDocument(new StreamReader(FileName, System.Text.Encoding.GetEncoding("windows-1256"))); XslCompiledTransform myXslTrans = new XslCompiledTransform(); myXslTrans.Load("D:/GS/xsl/test.xsl"); XmlTextWriter myWriter = new XmlTextWriter(destinationFile, null); myWriter.Formatting = Formatting.Indented; myWriter.Indentation = 4; myXslTrans.Transform(myXPathDoc, null, myWriter); myWriter.Close(); } catch (Exception e) { Console.WriteLine("The process failed: {0}", e.ToString()); } finally { Monitor.Exit(lockObject); watcher.EnableRaisingEvents = true; GC.Collect(); GC.WaitForPendingFinalizers(); GC.Collect(); } 

在添加这些行之前,代码工作正常。 这些主要用于测试xml文件是否没有我通常得到的结束标记(然后添加标记)。 添加以下代码后,它开始给我这个例外。

 try { XmlDocument xdoc = new XmlDocument(); xdoc.Load(FileName); xdoc = null; } catch (XmlException xe) { using (StreamWriter w = File.AppendText(FileName)) { Console.WriteLine(xe); w.WriteLine(""); w.WriteLine(""); } } 

这可能有什么问题?

编辑:错误我得到了

进程失败:System.IO.IOException:进程无法访问文件’z:\ TF_B1BBA.xml’,因为它正被另一个进程使用。 在System.IO .__ Error.WinIOError(Int32 errorCode,String maybeFullPath)at System.IO.FileStream.Init(String path,FileMode mode,FileAccess access,I nt32 rights,Boolean useRights,FileShare share,Int32 bufferSize,FileOptions o ptions, UCE uri,System.Xml.XmlDownloadManager。 System.Threading.CompressedStack.runTryCode(Object)上System.Xml.XmlTextReaderImpl.OpenUrlDelegate(Object xmlResolver)的System.Xml.XmlUrlResolver.GetEntity(Uri absoluteUri,String role,Type ofO bjectToReturn)中的ICredentials凭据,IWebProxy代理,RequestCachePolicy cachePolicy) System.Threading.CompressedStack.Run(CompressedStack compressedStac)上的System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCl eanup(TryCode代码,CleanupCode backoutCode,Object userData)上的userData) 在System.Xml.XmlTextReaderImpl.Read()的System.Xml.XmlTextReaderImpl.OpenUrl()处的k,Cont extCallback回调,对象状态。 位于System.Xml.XmlDocument.Load(XmlReader reader)的System.Xml.XmlLoader.Load(XmlDocument doc,XmlReader reader,Boolean prese veWhitespace),位于GSelInterface.Program.convert的System.Xml.XmlDocument.Load(String filename)处(对象源,FileSystemEventArgs f)在C:\ Documents and Settings \ Administrator \ Desktop \ ConsoleApplication1 \ ConsoleApplicat ion1 \ Program.cs:第178行

在您的try块中,您已打开该文件。 你需要关闭它。

 XmlDocument xdoc = new XmlDocument(); xdoc.Load(FileName); 

请遵循此示例。

http://msdn.microsoft.com/en-us/library/zcsyk915.aspx

这可能是因为观察者(然后FileShare.ReadWrite是重要部分)。

尝试:

 XmlDocument xdoc = new XmlDocument(); FileStream fs = new FileStream(FileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); xdoc.Load(fs); 

您正在尝试写入已在try块中打开的“Filename”文件。

编辑1:

似乎锁是由保存文件的进程设置的。 当触发convert()时,文件系统仍未完成保存文件。 特别是如果你有一个大的xml,它会发生。 如果在尝试写入文件之前添加睡眠,则不会引发exception。

这是一个快速而肮脏的补丁。

如果以高频率保存xml文件,则需要为更改的xml文件添加某种锁定。

编辑2:

尝试在执行操作之前删除观察者的事件,并在完成所有操作后再次添加,以防止触发多个事件。 不确定EnableRaisingEvents = false将以正确的方式工作。 也看到这篇文章:

EnableRaisingEvents(启用和禁用它)

 try { watcher.EnableRaisingEvents = false; //Edit2: Remove the watcher event watcher.Changed -= new FileSystemEventHandler(convert); try { XmlDocument xdoc = new XmlDocument(); xdoc.Load(FileName); } catch (XmlException xe) { System.Threading.Thread.Sleep(1000); //added this line using (StreamWriter w = File.AppendText(FileName)) { Console.WriteLine(xe); w.WriteLine(""); w.WriteLine(""); } } } /* Here all xslt transform code */ //Edit2: Add again the watcher event watcher.Changed += new FileSystemEventHandler(convert); } catch (Exception e) { Console.WriteLine("The process failed: {0}", e.ToString()); } 

这个问题的解决方案就在这个链接上:

xml处理期间的exception

这是我提出的另一个问题。 谢谢你们所有花时间帮助我的人。

确保该文件不存在。

我不得不重新创建我的构建配置,旧文件仍然存在。 一旦我删除了旧的变换,我就能够重新创建新的变换。