.NET文件锁定问题

xqk2d5yq  于 2023-01-14  发布在  .NET
关注(0)|答案(3)|浏览(170)

我目前正在执行以下操作:

  • 我使用using()标记中的花括号FileStream创建了一个文件--只有文件创建发生在using语句中,其余语句几乎是连续的。
  • 启动我使用Process.Start()创建的文件
  • 使用Assembly.ReflectionOnlyLoadFrom()从文件中读取少量 meta数据
  • 使用Process.GetProcessesByName列出正在运行的进程
  • 使用Process.Kill终止进程
  • 尝试使用File.Delete()删除该文件

我的问题是我的应用程序锁定了文件,所以当我尝试删除它时,什么也没发生。如果我尝试删除它,它会抛出一个异常,说“Access is Denied”;如果我尝试写入它,它会抛出“Another process is using this file”。
究竟是什么在消耗上面的文件(字面上所有的)?我已经设置了所有对null的引用,甚至调用了可怕的GC.Collect(),但没有运气。

qoefvg9y

qoefvg9y1#

当你加载程序集时,它承载在当前的AppDomain中。如果你使用ReflectionOnlyLoad(byte[])加载它,它将作为影子加载,并且不会锁定文件。

var bytes = File.ReadAllBytes(path);
var assembly = Assembly.ReflectionOnlyLoad(bytes);

目前,阻止文件的代码是Assembly.ReflectionOnlyLoadFrom(),而不是写入文件(假设在尝试删除之前释放了FileStream)。仅当卸载AppDomain时才会释放该文件。

owfi6suc

owfi6suc2#

显然,您在代码中执行的操作会导致程序集在您自己的进程中加载。一旦加载到进程中,程序集就会被卡住,文件也会被锁定,直到加载程序集的AppDomain卸载为止。这无疑是最主要的原因,程序集会被卡住,直到程序终止。
请注意Visual Studio的“输出”窗口,加载该窗口后,您将立即收到调试器通知。在查看该窗口的同时单步执行代码,将很容易隔离导致该窗口的语句。

brqmpdu1

brqmpdu13#

你可以用Process Monitor工具做一个分析。它可以捕获每个文件访问的调用栈,因此应该足以告诉你文件在哪里/什么时候被锁定。

相关问题