2012-01-06 14 views
11

Estoy escribiendo una solución donde uso algunos archivos de configuración que deberían poder editarse en tiempo de ejecución. He estado usando FileSystemWatcher para este fin antes y nunca he tenido demasiados problemas, pero ahora está causando un CTD en el evento 'rename'.FileSystemWatcher causa bloqueo en el escritorio

Este (inútil) pieza de código volverá a crear el problema en mi configuración:

private static int _s_renamed; 
private static int _s_created; 
private static int _s_errors; 

private static void monitorConfiguration(string configRootFolder) 
{ 
    var fsw = new FileSystemWatcher(configRootFolder, ConfigFilePattern) 
    { 
     NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.FileName, 
     IncludeSubdirectories = false 
    }; 
    fsw.Renamed += (sender, args) => ++_s_renamed; // <-- ! CTD efter this one ! 
    fsw.Created += (sender, args) => ++_s_created; 
    fsw.Error += (sender, args) => ++_s_errors; 
    fsw.EnableRaisingEvents = true; 
} 

El accidente viene de FileSystemWatcher que parece. Si configuro un punto de interrupción en el controlador de eventos para FileSystemWatcher.Renamed, se golpea pero la aplicación falla cuando salgo de ella. Si configuro un punto de interrupción en el controlador de eventos FileSystemWatcher.Created, esto no ocurre.

¿Alguna sugerencia?


EDIT 1: estoy ejecutando .NET 4 en un x64 de Windows 7 (Ultimate) plataforma he visto varias discusiones relativas a este tipo de problemas, pero todo se ha relacionado con la gente tratando de actualizar cosas UI (que debe hacerse desde el hilo principal/UI) desde los controladores de eventos. Es por eso que trato de incrementar algunos contadores en el código experimental.

+2

¿Existe una excepción? – David

+0

No, la aplicación se bloquea en el escritorio y parece que no puedo verla. Es una aplicación WPF y capturo todas las excepciones no controladas (Application.DispatcherUnhandledException) pero esta no está atrapada. –

+0

¿Qué es un CTD y qué hace? – Gabe

Respuesta

1

Solo para aclarar:

El problema aquí era que tenía más consumidores/mayores de la FileSystemWatcher en otra parte de mi sistema y uno de ellos provocó una excepción no controlada. El problema es que la excepción se lanza en un hilo completamente diferente y hace que la aplicación se bloquee en el escritorio. El tiempo me engañó y me hizo pensar que era mi nuevo consumidor el que de alguna manera causaba el error, pero cuando seguí el consejo de Chris Shain (ver comentarios en la entrada de la pregunta) para habilitar las excepciones (msdn.microsoft.com/en-us/library/d14azbfh.aspx) encontré al verdadero culpable.

Hubiera preferido dar crédito a Chris con la solución, pero nunca volvió a publicar, así que aquí está.Espero haber aprendido algo.

Gracias a todos y feliz de codificación

/Jonas

0

Puede estar ejecutando en ninguna de estas tres situaciones

  1. El directorio en el pasado no existe y un archivo IO no existente se está lanzando.
  2. El directorio pasado es válido pero el proceso que lo ejecuta no tiene derechos de acceso
  3. Los argumentos (remitente, args) como pasados, uno puede ser nulo y su código (ya que este es un ejemplo y podemos ' t ver el código real) no está manejando el nulo y arrojando un error.
0

En .NET debe sincronizar el hilo generado por FileSystemWatcher con el subproceso UI. Para esto, los controles de UI tienen un método como: myControl.Invoke (...) para este efecto. Cualquier otra forma de intentar sincronizar tendrá algunos efectos aleatorios como crashs, excepciones, etc.

ver aquí: http://msdn.microsoft.com/en-us/magazine/cc300429.aspx http://weblogs.asp.net/justin_rogers/pages/126345.aspx

Esperamos que ayude

0

Tal vez su archivo u objeto están en uso, tuve un problema similar y lo resolví usando el siguiente código

private void InitWatch() 
{ 
    FileSystemWatcher watcher = new FileSystemWatcher(); 
    watcher.Path = @"C:\LoQueSea"; 
    watcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite 
    | NotifyFilters.FileName | NotifyFilters.DirectoryName; 
    watcher.Filter = "*.*"; 
    watcher.Created += new FileSystemEventHandler(OnCreated); 
    watcher.EnableRaisingEvents = true; 
} 
private void OnCreated() 
{ 
    try 
    { 
     if (!myObjectToPrint.Dispatcher.CheckAccess()) 
     { 
      myObjectToPrint.Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Normal, 
       new Action(
        delegate() 
        { 
        //your code here... 
        } 
        ) 
     } 
    } 
    catch (Exception ex) 
    { 
     throw ex; 
    }   
} 

Saludos ..

+0

¿Por qué? 'Try {} catch (Exception ex) {throw ex; } '? Esto no hace nada aparte de arruinar el seguimiento de la pila, lo que dificulta la depuración. – tomfanning

+0

También esto no parece tener mucha relación con el problema informado por el OP (excepción no controlada en FileSystemWatcher después de que se haya activado el evento Renamed) – tomfanning

+0

Este tipo de captura aparentemente inútil ... puede ser útil para la depuración. Colocar un punto de interrupción en el "tiro ex" le dará la capacidad de examinar lo que está sucediendo cuando está tratando de resolver alguna excepción inesperada. Debería eliminarse cuando hayas terminado, por supuesto. –