Вопрос

Мы только что столкнулись со странной проблемой с 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?

Это было полезно?

Решение

Просто мысль...Есть ли вероятность, что здесь какая-то тупиковая проблема?

Вы вызываете TreeView.Invoke, который является блокирующим вызовом.Если изменение файловой системы происходит как раз в тот момент, когда вы нажимаете любую кнопку, запускается FileSystemWatcher.При вызове Dispose() ваш метод FileWatcherFileChanged будет вызван в фоновом потоке и вызовет TreeView .Вызов, который будет заблокирован до тех пор, пока ваш поток формы не сможет обработать запрос Invoke .Однако ваш поток формы будет вызывать FileSystemWatcher.Dispose(), который, вероятно, не вернется, пока не будут обработаны все ожидающие запросы на изменение.

Попробуйте изменить .Invoke на .BeginInvoke и посмотрите, поможет ли это.Это может помочь направить вас в правильном направлении.

Конечно, это также может быть проблема с .NET 3.5SP1.Я просто строю предположения, основываясь на предоставленном вами коде.

Другие советы

Скотт, мы иногда сталкивались с проблемами с управлением.Вызывайте в .NET 2.Попробуйте переключиться на control.BeginInvoke и посмотрите, поможет ли это.

Выполнение этого позволит потоку FileSystemWatcher немедленно вернуться.Я подозреваю, что ваша проблема каким-то образом заключается в том, что элемент управления.Invoke блокируется, что приводит к зависанию FileSystemWatcher при dispose.

У нас тоже есть эта проблема.Наше приложение работает на платформе .Net 2.0, но скомпилировано с помощью версии 2008 SP1.У меня также установлен .NET 3.5 SP1.Я также понятия не имею, почему это происходит, это не похоже на проблему взаимоблокировки с нашей стороны, поскольку на данный момент никакие другие потоки не запущены (это происходит во время завершения работы приложения).

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top