2011-11-21 30 views
5

Tengo un problema al trabajar con filesystemwatcher, me está volviendo loco.FileSystemWatcher de .NET se bloquea cuando se produce una excepción, el archivo throws está en uso para archivos futuros

Resulta que estoy viendo para los nuevos archivos de texto en una carpeta, cuando se eleva el Evento creado, básicamente leí usando el siguiente código:

string txtTemp = File.ReadAllText(MyFilePath); 

Después de eso, procesar los datos en el txtTemp cadena, básicamente, leí sus líneas & almacenar los datos en un DB, bastante simple, ¿no?

El problema es cuando se produce una excepción en este proceso (digamos conexión db no), no importa si lo cojo porque durante los siguientes archivos próximos la aplicación arrojará una excepción diciendo

"El proceso no puede acceder al archivo 'theNewComingFile.txt' porque es que está siendo utilizado por otro proceso."

¿Cómo es que el nuevo archivo creado podría estar en uso si ni siquiera se ha abierto o leído? Y la aplicación sigue arrojando esta excepción de "proceso no puede acceder al archivo" para todos los archivos nuevos.

La única cosa que podemos hacer es cerrar y volver a abrir la aplicación, esto restablece la aplicación y todo funciona bien otra vez hasta que una excepción de cualquier tipo se eleva de nuevo> (Gosh!)

¿Alguna idea? cualquier solución? ¿Alguna idea? alguna sugerencia alguna ... ¿algo? hehehehe =)

Gracias tíos !!

+0

¿Es posible que esté configurando otro FileSystemWatcher en caso de una excepción, y ambos están compitiendo para manejar el mismo archivo? ¿Podría publicar su código de gestión de eventos, así como el código de configuración FileSystemWatcher? – zmbq

+0

Más código sería útil – jtm001

+0

['File.ReadAllText()'] (http://msdn.microsoft.com/en-us/library/ms143368.aspx): "Abre un archivo de texto, lee todas las líneas del archivo , ** y luego cierra el archivo **. ". No debería suceder siempre que la excepción no se plantee desde allí. ¿No puedes probar un StreamReader para leer el archivo? – CodeCaster

Respuesta

5

puede iniciar su investigación utilizando el Sysinternals Process Explorer. Le dará más detalles, particularmente sobre qué proceso contiene el archivo.

+0

Esta no fue la respuesta, pero fue tan útil que di para siempre :-D –

-1

Una solución temporal es simple: ponga a su observador en su propio Dominio de aplicación, corte el AppDomain y reinicie si maneja una excepción. Esto probablemente solucionará su problema. ¿Pero por qué sucede? Tendré que pensarlo un poco, y tal vez encontrar algo.

+3

Vamos a poner un barco en nuestro bote para cuando nuestro bote se hunda. ¿Y si el segundo barco se hunde? ¡Pon en otro bote! – CodeCaster

+0

jaja sí, cierto amigo! –

+0

Se llaman botes salvavidas. Cada barco los tiene en caso de que el barco se hunda. De todos modos ... si FileSystemWatcher tiene una falla crítica, entonces esta sugerencia puede ser una opción legítima. Habiendo dicho eso, el aislamiento probablemente sea innecesario, porque el problema es simplemente un manejador de archivo abierto. – Triynko

2

El evento Creado se activa antes de que el archivo haya terminado de escribirse por completo.

De MSDN:

El evento OnCreated se eleva tan pronto como se crea un archivo. Si un archivo se está copiando o transfiriendo a un directorio vigilado, el evento OnCreated se activará inmediatamente, seguido de uno o más eventos OnChanged .

Por lo tanto, obtener la excepción que describe sería bastante normal. Cuando me he enfrentado a esta situación, básicamente pruebo el archivo primero para ver si puedo acceder o no. Aquí está la función que uso:

private static bool GetExclusiveAccess(string filePath) 
    { 
    try 
    { 
     using (FileStream file = new FileStream(filePath, FileMode.Append, FileAccess.Write)) 
     { 
      file.Close(); 
      return true; 
     } 
    } 
    catch (IOException) 
    { 
     return false; 
    } 
    } 

Si no tiene acceso, tendrá que esperar y volver a verificar.

+0

Nop, no estoy haciendo frente al archivo, se creó desde una aplicación diferente, pero digamos que ese era el problema, ¿por qué si lo reinicio después de la excepción, funciona bien? –

+0

No tiene que ver con copiar el archivo. Cualquier archivo que se crea primero tiene que ser creado y luego se "llena" con contenido y luego se cierra. Todo durante el "llenado" está bloqueado por el creador del archivo. Pero el FileSystemWatcher dispara el evento OnCreated justo después de la creación. Entonces tiene una condición de carrera entre el creador del archivo y el código que responde al evento OnCreated. Si se trata de un archivo súper pequeño, entonces el relleno se puede realizar cuando su thread obtenga OnCreated. Pero normalmente verás lo que describes. El creador del archivo todavía lo está "llenando". –

+0

Gracias Russell McClure, probaré esto hoy e intentaré implementar su solución, y luego se lo haré saber. Gracias de nuevo ! –

2

Puede ser que al abrir el archivo cambie la marca de tiempo de la última lectura: esto podría causar un bucle.

Es posible que desee intentar cambiar su diseño para que los eventos se coloquen en una cola si (y solo si) el archivo no está en cola para su procesamiento. A continuación, puede atrapar excepciones, etc., bajo el control adecuado de la otra cadena sin interferir con el Observador.

[He visto casos de esquina muy interesantes con FileSystemWatcher en el pasado - puede ser un poco bestial cuando se arrincona. Uno (hace un tiempo) provocó un bloqueo de pantalla azul no reproducible en Windows Server 2003 cuando un búfer interno se desbordó porque estaba inundado de eventos. Mejor cuidado.]

Cuestiones relacionadas