0

我不明白为什么相同的代码在 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);           
    }            
}
4

2 回答 2

3

当您使用时,using您不需要关闭Stream,因为它会自动关闭Streamafter using; 所以试试这个代码:

 using (FileStream fs = new FileStream(assemblyFile, FileMode.Open, FileAccess.Read, FileShare.Read))
    {
        //read a file and write to memorystream.
    }
于 2013-06-10T03:40:35.930 回答
0

您需要处理此异常,这对于您的应用程序来说是绝对正常的情况。想象一下,某个应用程序获取了文件的独占权并对其进行了修改——您将得到相同的异常。但是你不能用它做任何事情——只是等待应用程序释放文件的时间。

在异常处理程序中,您可能会将此类未成功加载的程序集放入某个集合并尝试稍后处理它(例如通过计时器)。

此外,对于您的应用程序来说,在文件更改时不完全加载程序集可能是更好的架构。将其放入队列中,对更改进行分组并定期加载。您将避免不必要的加载(在多次更改的情况下)并从文件系统事件处理中拆分加载逻辑。

于 2013-06-10T05:04:48.540 回答