我不明白为什么相同的代码在32位系统上成功运行,但尝试在64位系统上运行它总是会出错:
另一个进程正在使用的文件
我声明文件观察者事件以观察文件已更改。
我的代码类似于以下内容:
static void Main()
{
//init load file
LoadAssembly(dll);
//bind watching event.
FileSystemWatcher watcher = new FileSystemWatcher(rootPath, "*.dll");
watcher.NotifyFilter = NotifyFilters.CreationTime | NotifyFilters.LastWrite;
watcher.Changed += new FileSystemEventHandler(TemplateFile_Changed);
watcher.IncludeSubdirectories = false;
watcher.EnableRaisingEvents = true;
}
private LoadAssembly(assemblyFile)
{
try
{
using (FileStream fs = new FileStream(assemblyFile, FileMode.Open, FileAccess.Read, FileShare.Read))
{
//read a file and write to memorystream.
......
fs.Close();
fs.Dispose();
}
asm = Assembly.Load(ms.ToArray());
}
finally
{
ms.Close();
}
}
private void TemplateFile_Changed(object sender, FileSystemEventArgs e)
{
lock (_sync)
{
LoadAssembly(e.FullPath);
}
}
我测试可以在32位系统中工作的代码(在我的计算机中)。当我部署到64位系统时,当我更改文件并告诉应用程序需要重新加载此文件时,总是得到一个
另一个进程使用的文件`
在
using (FileStream fs = new FileStream(assemblyFile, FileMode.Open, FileAccess.Read, FileShare.Read))
更新-1
好吧,谢谢@Hans Passant回答,这个异常是由文件观察者发起的,它触发了一个已更改的事件并仍保持文件打开状态。我在TemplateFile_Changed中添加一个Thread.Sleep()看起来解决了这个问题。
private void TemplateFile_Changed(object sender, FileSystemEventArgs e)
{
lock (_sync)
{
Thread.Sleep(2000);
LoadAssembly(e.FullPath);
}
}
答案 0 :(得分:3)
当您使用using
时,您无需关闭Stream
,因为它会在Stream
之后自动关闭using
;所以试试这段代码:
using (FileStream fs = new FileStream(assemblyFile, FileMode.Open, FileAccess.Read, FileShare.Read))
{
//read a file and write to memorystream.
}
答案 1 :(得分:0)
您需要处理此异常,这对您的应用程序来说绝对是正常情况。想象一下,某些应用程序获取文件的独占权并修改它 - 您将获得相同的异常。但是你无能为力 - 只需等待应用程序释放文件。
在异常处理程序中,您可能会将这些未成功加载的程序集放到某个集合中,并尝试稍后处理它(例如,通过计时器)。
此外,您的应用程序可能更好的架构不能在文件更改时完全加载程序集。将其置于队列中,对组进行更改并定期加载。您将避免不必要的加载(在多次更改的情况下)并从文件系统事件处理中拆分加载逻辑。