2011-05-31 54 views
13

Estoy escribiendo un programa C# para avisarme cuando se ha agregado o eliminado un archivo. Lo ejecuto en mi máquina con Windows 7 y miro un servidor FTP en nuestra red.FileSystemWatcher detiene la captura de eventos

Funciona bien pero de repente dejará de detectar cualquier evento. Supongo que podría estar perdiendo conexión con el servidor o que hay una falla en la red.

Cómo puedo manejar esta situación en el código. ¿Hay alguna excepción que pueda observar e intentar reiniciar el objeto FileSystemWatcher?

Cualquier sugerencia y ejemplos de código serían apreciados.

+0

Así que si 1kb del archivo se ha cargado, ¿cómo sabes que la transmisión esté completa? Creo que necesitas repensar tu enfoque aquí. – leppie

+0

Consulte esta pregunta sobre excepciones al leer archivos creados con FileSystemWatcher http://stackoverflow.com/questions/699538/file-access-error-with-filesystemwatcher-when-multiple-files-are-added-to-a- direc –

+0

Funciona bien para capturar cuando se crean o eliminan archivos. Solo necesito saber cómo recuperarme de la conexión perdida o falla de la red. ¿Hay algún tipo de excepción lanzada en el objeto FileSystemWatcher? – Paul

Respuesta

10

La respuesta anterior no lo soluciona completamente, tuve que reiniciar el monitor no solo encenderlo y apagarlo. utilizo FileSystemWatcher en un servicio ventana

void NotAccessibleError(FileSystemWatcher source, ErrorEventArgs e) 
{ 
    int iMaxAttempts = 120; 
    int iTimeOut = 30000; 
    int i = 0; 
    while ((!Directory.Exists(source.Path) || source.EnableRaisingEvents == false) && i < iMaxAttempts) 
    { 
     i += 1; 
     try 
     { 
      source.EnableRaisingEvents = false; 
      if (!Directory.Exists(source.Path)) 
      { 
       MyEventLog.WriteEntry("Directory Inaccessible " + source.Path + " at " + DateTime.Now.ToString("HH:mm:ss")); 
       System.Threading.Thread.Sleep(iTimeOut); 
      } 
      else 
      { 
       // ReInitialize the Component 
       source.Dispose(); 
       source = null; 
       source = new System.IO.FileSystemWatcher(); 
       ((System.ComponentModel.ISupportInitialize)(source)).BeginInit(); 
       source.EnableRaisingEvents = true; 
       source.Filter = "*.tif"; 
       source.Path = @"\\server\dir"; 
       source.NotifyFilter = System.IO.NotifyFilters.FileName; 
       source.Created += new System.IO.FileSystemEventHandler(fswCatchImages_Changed); 
       source.Renamed += new System.IO.RenamedEventHandler(fswCatchImages_Renamed); 
       source.Error += new ErrorEventHandler(OnError); 
       ((System.ComponentModel.ISupportInitialize)(source)).EndInit(); 
       MyEventLog.WriteEntry("Try to Restart RaisingEvents Watcher at " + DateTime.Now.ToString("HH:mm:ss")); 
      } 
     } 
     catch (Exception error) 
     { 
      MyEventLog.WriteEntry("Error trying Restart Service " + error.StackTrace + " at " + DateTime.Now.ToString("HH:mm:ss")); 
      source.EnableRaisingEvents = false; 
      System.Threading.Thread.Sleep(iTimeOut); 
     } 
    } 
} 
+0

esto parece seguir haciendo bucles y volver a crear el sistema de archivos vigilante, incluso si es exitoso en algún momento. ¿No debería haber una ruptura en el ciclo de "éxito"? – Matt

+0

@Matt Debería interrumpirse 1) la ruta existe (accesible) yb) EnableRaisingEvents == true. –

16

que tenía que añadir un controlador de errores para la FileSystemWatcher

fileSystemWatcher.Error += new ErrorEventHandler(OnError); 

Y a continuación, agregue este código:

private void OnError(object source, ErrorEventArgs e) 
{ 
    if (e.GetException().GetType() == typeof(InternalBufferOverflowException)) 
    { 
     txtResults.Text += "Error: File System Watcher internal buffer overflow at " + DateTime.Now + "\r\n"; 
    } 
    else 
    { 
     txtResults.Text += "Error: Watched directory not accessible at " + DateTime.Now + "\r\n"; 
    } 
    NotAccessibleError(fileSystemWatcher ,e); 
} 

Aquí es cómo puedo restablecer el objeto SystemFileWatcher:

static void NotAccessibleError(FileSystemWatcher source, ErrorEventArgs e) 
    { 
     source.EnableRaisingEvents = false; 
     int iMaxAttempts = 120; 
     int iTimeOut = 30000; 
     int i = 0; 
     while (source.EnableRaisingEvents == false && i < iMaxAttempts) 
     { 
      i += 1; 
      try 
      { 
       source.EnableRaisingEvents = true; 
      } 
      catch 
      { 
       source.EnableRaisingEvents = false; 
       System.Threading.Thread.Sleep(iTimeOut); 
      } 
     } 

    } 

Creo que este código debería hacer lo que quiero que haga.

+0

Si esto realmente soluciona el problema, debe marcarlo como la respuesta. Por lo que vale, ¿cuál fue la excepción que se lanzó? –

+0

Chris, En realidad, no me preocupa la excepción. Solo quiero asegurarme de que el objeto FileSystemWatcher se reinicie. – Paul

Cuestiones relacionadas