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

after ;を使用しているときは、自動的に終了するため、終了usingする必要はありません。このコードを試してください:StreamStreamusing

 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 に答える