2008-09-16 18 views
7

Acabamos de empezar a ejecutar un problema extraño con un FileSystemWatcher donde la llamada a Dispose() parece estar colgando. Este es un código que ha estado funcionando sin problemas por 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 el FileSystemWatcher:FileSystemWatcher Dispose call cuelga

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 esto se esté utilizando para actualizar la imagen del estado de un objeto TreeNode (ajustado ligeramente para eliminar la información específica de 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; 
     } 
     } 
    } 
} 

Es Hay algo que nos falta o es una anomoly de .NET3.5 SP1?

Respuesta

7

Solo un pensamiento ... ¿Hay alguna posibilidad de que haya un problema de estancamiento aquí?

Está llamando a TreeView.Invoke, que es una llamada de bloqueo. Si ocurre un cambio en el sistema de archivos justo cuando hace clic en el botón que causa la llamada FileSystemWatcher.Dispose(), se llamará a su método FileWatcherFileChanged en una cadena de fondo y llamará TreeView.Invoke, que bloqueará hasta que su cadena de caracteres pueda procesar la solicitud Invoke. . Sin embargo, su cadena de formulario estaría llamando a FileSystemWatcher.Dispose(), que probablemente no se devuelva hasta que se procesen todas las solicitudes de cambio pendientes.

Intenta cambiar el .Invocar a .BeginInvoke y ver si eso ayuda. Eso puede ayudarlo a apuntar en la dirección correcta.

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

1

También estamos teniendo este problema. Nuestra aplicación se ejecuta en .Net 2.0 pero es compilada por VS 2008 SP1. Tengo .NET 3.5 SP1 instalado también. No tengo ni idea de por qué sucede esto, tampoco parece un problema de interbloqueo en nuestro extremo, ya que no hay otros subprocesos en ejecución en este punto (es durante el apagado de la aplicación).

+0

Si está utilizando un FileSystemWatcher, potencialmente está utilizando otro hilo; el subproceso FileSystemWatcher podría bloquearse al intentar invocar el subproceso de la interfaz de usuario. –

2

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

Esto permitirá que la cadena FileSystemWatcher regrese inmediatamente. Sospecho que su problema es que el control. Invoke está bloqueando, lo que hace que FileSystemWatcher se congele al deshacerse de él.

+0

Este parece ser el caso y la solución correcta. Le concedí la respuesta a Jonathan, ya que él fue el primero en responder. –