11

Dispose() の呼び出しがハングしているように見える FileSystemWatcher で奇妙な問題が発生し始めました。これはしばらく問題なく動作しているコードですが、.NET3.5 SP1 にアップグレードしたばかりなので、他の誰かがこの動作を見たかどうかを調べようとしています。FileSystemWatcher を作成するコードは次のとおりです。

if (this.fileWatcher == null)
{
   this.fileWatcher = new FileSystemWatcher();
}
this.fileWatcher.BeginInit();
this.fileWatcher.IncludeSubdirectories = true;
this.fileWatcher.Path = project.Directory;
this.fileWatcher.EnableRaisingEvents = true;
this.fileWatcher.NotifyFilter = NotifyFilters.Attributes;
this.fileWatcher.Changed += delegate(object s, FileSystemEventArgs args)
{
   FileWatcherFileChanged(args);
};
this.fileWatcher.EndInit();

これが使用されている方法は、TreeNode オブジェクトの状態イメージを更新することです (ビジネス固有の情報を削除するためにわずかに調整されています)。

private void FileWatcherFileChanged(FileSystemEventArgs args)
{
   if (this.TreeView != null)
   {
      if (this.TreeView.InvokeRequired)
      {
         FileWatcherFileChangedCallback d = new FileWatcherFileChangedCallback(FileWatcherFileChanged);
         this.TreeView.Invoke(d, new object[]
      {
         args
      });
      }
      else
      {
         switch (args.ChangeType)
         {
            case WatcherChangeTypes.Changed:
               if (String.CompareOrdinal(this.project.FullName, args.FullPath) == 0)
               {
                  this.StateImageKey = GetStateImageKey();
               }
               else
               {
                  projectItemTreeNode.StateImageKey = GetStateImageKey();
               }
               break;
         }
      }
   }
}

不足しているものはありますか、それとも .NET3.5 SP1 からの異常ですか?

4

3 に答える 3

9

考えただけです...ここでデッドロックの問題が発生する可能性はありますか?

ブロッキング呼び出しである TreeView.Invoke を呼び出しています。FileSystemWatcher.Dispose() 呼び出しを引き起こすボタンをクリックしているときにファイルシステムの変更が発生した場合、FileWatcherFileChanged メソッドがバックグラウンド スレッドで呼び出され、フォーム スレッドが Invoke 要求を処理できるようになるまでブロックされる TreeView.Invoke を呼び出します。 . ただし、フォーム スレッドは FileSystemWatcher.Dispose() を呼び出しており、保留中のすべての変更要求が処理されるまで返されない可能性があります。

.Invoke を .BeginInvoke に変更してみて、それが役立つかどうかを確認してください。それはあなたを正しい方向に向けるのに役立つかもしれません。

もちろん、.NET 3.5SP1 の問題である可能性もあります。私はあなたが提供したコードに基づいてここで推測しています。

于 2008-09-16T14:52:27.397 に答える
2

Scott さん、私たちは .NET 2 で control.Invoke に関する問題を時々見てきました。

これを行うと、FileSystemWatcher スレッドがすぐに戻ることができます。あなたの問題は、control.Invokeがブロックされているため、破棄時にFileSystemWatcherがフリーズすることが何らかの形であると思われます。

于 2008-09-30T16:42:07.387 に答える
1

この問題も発生しています。このアプリケーションは.Net2.0で実行されますが、VS2008SP1によってコンパイルされます。.NET3.5SP1もインストールしています。なぜこれが発生するのかわかりません。この時点では他のスレッドが実行されていないため(アプリケーションのシャットダウン中)、デッドロックの問題のようには見えません。

于 2008-09-17T22:33:35.733 に答える