关于c#:FileSystemWatcher Dispose调用挂起

关于c#:FileSystemWatcher Dispose调用挂起

FileSystemWatcher Dispose call hangs

我们刚刚开始遇到FileSystemWatcher的一个奇怪问题,其中对Dispose()的调用似乎挂起了。这段代码已经运行了一段时间,没有任何问题,但是我们刚刚升级到.NET3.5 SP1,因此我试图找出是否有人看到了此行为。以下是创建FileSystemWatcher的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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对象的状态图像(略微调整以删除特定于业务的信息):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
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的异常?


只是一个想法...这里是否有死锁问题?

您正在调用TreeView.Invoke,这是一个阻止调用。如果在单击任何按钮导致FileSystemWatcher.Dispose()调用时发生文件系统更改,则FileWatcherFileChanged方法将在后台线程上调用并调用TreeView.Invoke,它将阻塞直到表单线程可以处理Invoke请求为止。但是,您的表单线程将调用FileSystemWatcher.Dispose(),在处理所有未决的更改请求之前,它可能不会返回。

尝试将.Invoke更改为.BeginInvoke,看看是否有帮助。这可能会帮助您指出正确的方向。

当然,这也可能是.NET 3.5SP1问题。我只是根据您提供的代码在这里推测。


Scott,我们偶尔会看到control.invoke在.NET 2中出现问题。尝试切换到control.BeginInvoke,看看是否有帮助。

这样做将允许FileSystemWatcher线程立即返回。我怀疑您的问题在某种程度上是control.invoke被阻止,从而导致FileSystemWatcher在处置时冻结。


我们也遇到了这个问题。我们的应用程序在.Net 2.0上运行,但由VS 2008 SP1编译。我也安装了.NET 3.5 SP1。我也不知道为什么会发生这种情况,因为我们目前还没有其他线程在运行(这是在应用程序关闭期间),所以这看起来不像是一个死锁问题。


推荐阅读