2009-12-29 17 views
12

¿Hay alguna forma de eludir o eliminar el bloqueo de archivos que tiene otro subproceso sin eliminar el hilo?¿Es posible omitir un bloqueo de archivo en C# cuando otro subproceso/proceso utiliza un bloqueo exclusivo?

Estoy usando una biblioteca de terceros en mi aplicación que está realizando operaciones de solo lectura en un archivo. Necesito un segundo hilo leer el archivo al mismo tiempo para extraer algunos datos adicionales que la biblioteca de terceros no está exponiendo. Desafortunadamente, la biblioteca de terceros abrió el archivo utilizando un bloqueo de lectura/escritura y, por lo tanto, obtengo el habitual "El proceso no puede acceder al archivo ... porque está siendo utilizado por otro proceso".

Me gustaría evitar la precarga de todo el archivo con mi hilo porque el archivo es grande y causaría demoras no deseadas en la carga de este archivo y el uso excesivo de memoria. Copiar el archivo no es práctico debido al tamaño de los archivos. Durante el funcionamiento normal, dos hilos que golpean el mismo archivo no causarían problemas importantes de contención/rendimiento de E/S. No necesito una sincronización de tiempo perfecta entre los dos hilos, pero necesitan leer los mismos datos en medio segundo de cada uno.

No puedo cambiar la biblioteca de terceros.

¿Hay alguna solución a este problema?

+6

Un candado es un candado - si lo hubiera, no sería un candado ... –

+1

Y al igual que con muchos candados, parece que algunos desarrolladores de bibliotecas no entienden que menos es más. :-) También estaría contento con una solución inteligente. –

+4

Una posibilidad remota: ¿puedes abrir ese archivo como compartido _antes_ de tu biblioteca de terceros? Quizás implementaron algún mecanismo alternativo. –

Respuesta

5

Si inicia messing with the underlying file handle puede desbloquear partes, el problema es que la secuencia de acceso al archivo no está diseñada para manejar este tipo de alteración y puede terminar bloqueándose.

Mi recomendación fuerte es parchear la biblioteca de terceros, cualquier cosa que haga puede y explotará en condiciones reales.

1

Esto no soluciona su problema directamente, pero una herramienta como Unlocker logra lo que intenta hacer, pero a través de una interfaz de usuario de Windows.

2

En resumen, no puede hacer nada para que un tercero bloquee el archivo. Puedes salirte con la respuesta de Richard E que menciona la utilidad Unlocker.

Una vez que el tercero abre un archivo y establece el bloqueo en él, el sistema subyacente le dará a ese tercero un bloqueo para garantizar que ningún otro proceso pueda acceder a él. Hay dos líneas de pensamiento sobre esto.

  • Uso de inyección DLL para corregir el código para establecer explícitamente el bloqueo o desarmarlo. Esto puede ser peligroso ya que estarías jugando con la estabilidad de otro proceso, y posiblemente terminarás arruinando el proceso y generando dolor. Piénselo, el sistema subyacente está haciendo un seguimiento de los archivos abiertos por un proceso ... Inyección DLL en el punto y remienda el código - esto requiere conocimiento técnico para determinar qué proceso desea inyectar en el tiempo de ejecución y alterar las banderas al interceptar la API de Win32 llame al OpenFile(...).
  • Dado que esto fue etiquetado como .NET, ¿por qué no desensamblar el origen del tercero en archivos .il y alterar el indicador para que el bloqueo se comparta, reconstruir la biblioteca volviendo a compilar todos los archivos .il en un archivo DLL . Esto, por supuesto, requeriría rootear el código donde la apertura del archivo se lleva a cabo en alguna clase en alguna parte.

Eche un vistazo al podcast here. Y eche un vistazo aquí que explica cómo hacer la segunda opción resaltada arriba, here.

Espero que esto ayude, Saludos cordiales, Tom.

1

Cualquier nivel bajo truco para hacer esto puede resultar en una estrellarse hilo, corrupción de archivos o etc.

De ahí que pensé que me gustaría mencionar la segunda mejor opción, sólo tiene que esperar su turno y hasta sondeo el archivo no está bloqueado: https://stackoverflow.com/a/11060322/495455


no creo que esta segunda consejos le ayudará, pero lo más cercano (que yo sepa) sería DemandReadFileIO:

IntSecurity.DemandReadFileIO(filename); 

internal static void DemandReadFileIO(string fileName) 
{ 
    string full = fileName;    
    full = UnsafeGetFullPath(fileName); 
    new FileIOPermission(FileIOPermissionAccess.Read, full).Demand(); 
} 
1

Creo que este es un problema que se puede resolver con C++. Se es molesto, pero al menos funciona (como se explica aquí: win32 C/C++ read data from a "locked" file)

Los pasos son los siguientes:

  1. Abrir el archivo antes de la tercera biblioteca con fsopen y la bandera _SH_DENYNO
  2. Abra la presentar ante la tercera biblioteca
  3. Leer el archivo dentro de su código

Usted puede estar interesado en estos enlaces, así:

  1. Llamando C++ de C# (Possible to call C++ code from C#?)
  2. El enlace interno de este post con una muestra (http://blogs.msdn.com/b/borisj/archive/2006/09/28/769708.aspx)
1

Ha intentado hacer una copia falsa del archivo antes de su biblioteca de terceros lo agarra ... luego usa la copia real para sus manipulaciones, lógicamente esto solo sería considerado si el archivo del que estamos hablando es bastante pequeño. pero es una especie de trampa :) buena suerte

1

Si el archivo está bloqueado y no se está utilizando, entonces tiene un problema con la forma en que funciona el mecanismo de bloqueo/desbloqueo de archivos. Solo debe bloquear un archivo cuando lo está modificando y, a continuación, debe desbloquearlo inmediatamente para evitar situaciones como esta.

Cuestiones relacionadas