【问题标题】:FileSystemWatcher Dispose call hangsFileSystemWatcher Dispose 调用挂起
【发布时间】:2008-09-16 14:46:47
【问题描述】:

我们刚刚开始遇到 FileSystemWatcher 的一个奇怪问题,其中对 Dispose() 的调用似乎挂起。这是一段时间以来一直没有任何问题的代码,但我们刚刚升级到 .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 的异常现象?

【问题讨论】:

    标签: c# .net winforms filesystemwatcher


    【解决方案1】:

    只是一个想法...这里有没有可能出现死锁问题?

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

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

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

    【讨论】:

      【解决方案2】:

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

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

      【讨论】:

      • 这似乎是正确的解决方案。我将答案授予乔纳森,因为他是第一个做出回应的人。
      【解决方案3】:

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

      【讨论】:

      • 如果你正在使用 FileSystemWatcher,你可能正在使用另一个线程; FileSystemWatcher 线程可能会被阻止尝试在 UI 线程上调用。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-04-26
      • 2012-08-26
      • 1970-01-01
      相关资源
      最近更新 更多