Pregunta

Acabamos de empezar a encontrarnos con un problema extraño con FileSystemWatcher donde la llamada a Dispose() parece estar colgada.Este es un código que ha estado funcionando sin problemas durante un tiempo, pero acabamos de actualizar a .NET3.5 SP1, así que estoy tratando de averiguar si alguien más ha visto este comportamiento.Aquí está el código que crea 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();

La forma en que se utiliza esto es para actualizar la imagen de estado de un objeto TreeNode (ajustada ligeramente para eliminar información específica del negocio):

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;
         }
      }
   }
}

¿Hay algo que nos falta o es una anomalía de .NET3.5 SP1?

¿Fue útil?

Solución

Solo un pensamiento...¿Alguna posibilidad de que haya un problema de bloqueo aquí?

Estás llamando a TreeView.Invoke, que es una llamada de bloqueo.Si ocurre un cambio en el sistema de archivos justo cuando hace clic en cualquier botón que cause la llamada a FileSystemWatcher.Dispose(), su método FileWatcherFileChanged será llamado en un hilo en segundo plano y llamará a TreeView.Invoke, que se bloqueará hasta que su hilo de formulario pueda procesar la solicitud de Invocación. .Sin embargo, el hilo de su formulario llamaría a FileSystemWatcher.Dispose(), que probablemente no regrese hasta que se procesen todas las solicitudes de cambio pendientes.

Intente cambiar .Invoke a .BeginInvoke y vea si eso ayuda.Eso puede ayudarle a orientarse en la dirección correcta.

Por supuesto, también podría ser un problema de .NET 3.5SP1.Solo estoy especulando aquí según el código que proporcionaste.

Otros consejos

Scott, ocasionalmente hemos visto problemas con control.Invoke en .NET 2.Intente cambiar a control.BeginInvoke y vea si eso ayuda.

Hacer eso permitirá que el hilo FileSystemWatcher regrese inmediatamente.Sospecho que su problema es que de alguna manera el control.Invoke está bloqueando, lo que hace que FileSystemWatcher se congele al eliminarlo.

También estamos teniendo este problema.Nuestra aplicación se ejecuta en .Net 2.0 pero está compilada por VS 2008 SP1.También tengo instalado .NET 3.5 SP1.Tampoco tengo idea de por qué sucede esto, no parece un problema de bloqueo por nuestra parte ya que no se están ejecutando otros subprocesos en este momento (es durante el cierre de la aplicación).

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top