2008-09-18 14 views
6

En una aplicación web asp.net, quiero escribir en un archivo. Esta función primero obtendrá datos de la base de datos y luego escribirá el archivo plano.Quiere escribir en un archivo, pero puede tener potencialmente varios escritores a la vez, necesita bloquear

¿Qué se puede hacer para asegurarse de que se produce sólo 1 de escritura, y una vez que los occurrs de escritura, los otros hilos que tal vez quieran escribir en el fichero no hacerlo ya que la escritura se llevó a cabo.

Quiero tener esta escritura se hacen sólo si no se ha hecho en digamos 15 minutos.

Sé que hay una palabra clave de bloqueo, por lo que debería envolver todo en un bloqueo, y comprobar si se ha actualizado en 15 minutos o más, o viceversa?

actualización

flujo de trabajo:

Como se trata de una aplicación web, las múltiples instancias serán las personas que visitan una página web en particular. Podría usar la compilación en el sistema de caché, pero si asp.net recicla, será costoso reconstruir la caché, así que solo quiero escribirla en un archivo plano. Mi otra opción sería simplemente crear un servicio de Windows, pero eso es más trabajo para administrar lo que quiero.

+0

¿Están todas las escrituras sucediendo dentro de una única instancia de una sola aplicación? ¿O varias instancias de la aplicación intentarán escribir al mismo tiempo o las diferentes aplicaciones intentarán escribir al mismo tiempo? –

Respuesta

2

Sincronizar el código escrito para bloquear en un objeto compartido de modo que sólo un hilo se mete dentro del bloque. Otros esperan hasta que salga el actual.

lock(this) 
{ 
    // perform the write. 
} 

Actualización: Supuse que tiene un objeto compartido. Si se trata de procesos diferentes en la misma máquina, necesitarías algo así como un Mutex con nombre. Looky here for an example

+0

Creo que esto no funcionaría, por las razones que he explicado a continuación. – MarkR

1

No es mejor para bloquear una variable de objeto en lugar de toda la instancia?

0

No estoy seguro de que el bloqueo de .NET sea aplicable a diferentes procesos. Además, lock (this) solo excluirá otros hilos que están ejecutando el método en la misma instancia de "this", por lo que otros hilos, incluso en el mismo proceso, podrían ejecutarse simultáneamente en instancias diferentes.

Suponiendo que todos los procesos se están ejecutando en la misma máquina, el bloqueo de archivos debe hacerlo sin embargo.

Si está en máquinas diferentes, su kilometraje puede variar: win32 afirma tener bloqueo de archivos que funciona en una red, pero históricamente las aplicaciones que dependen de él (Think MSAccess) tienen problemas con la corrupción de archivos.

+0

Tiene razón en que para que el bloqueo funcione, necesitará todos los métodos para usar la misma instancia de "esto". La solución aquí podría ser crear una instancia de objeto ficticio ** estática ** que garantizará que. –

0
// try enter will return false if another thread owns the lock 
    if (Monitor.TryEnter(lockObj)) 
    { 
     try 
     { 
     // check last write time here, return if too soon; otherwise, write 
     } 
     finally 
     { 
     Monitor.Exit(lockobj); 
     } 
    } 
+0

que es exactamente lo mismo que lock (lockObj) {}. –

1

Las operaciones de E/S de archivos que se escriben en el archivo bloquearán automáticamente el archivo. Compruebe si el archivo está bloqueado (intentando la escritura) y si no lo está. Antes de escribir, verifique la marca de tiempo en el archivo y vea si es más de 15 minutos.

afaik no puede escribir en un archivo sin que Windows lo bloquee.

Ahora todo lo que queda para usted es buscar cómo hacer lo anterior utilizando msdn (lo siento, no me molesto en buscarlo todo y no recuerdo muy bien las clases de C#). :)

+1

Nota, mi respuesta depende de que las marcas de tiempo sean confiables, no siempre es una buena suposición. En su lugar, podría dejar el archivo abierto, simplemente sin escribir durante 15 minutos, después de que el proceso finalice la escritura. :) – jheriko

0

utilizar bloqueos del sistema de archivos

Al igual que otros sugirieron,.Los bloqueos NET serán de uso limitado en esta situación. Aquí está el código:

FileInfo fi = new FileInfo(path); 
if (fi.Exists 
    && (DateTime.UtcNow - fi.LastWriteTimeUtc < TimeSpan.FromMinutes(15)) { 
    // file is fresh 
    return; 
} 

FileStream fs; 
try { 
    fs = new FileStream(
    path, FileMode.Create, FileAccess.Write, FileShare.Read); 
} catch (IOException) { 
    // file is locked 
    return; 
} 

using (fs) { 
    // write to file 
} 

Esto funcionará a través de hilos y procesos.

0

Deberían considerar un Mutex. Se puede sincronizar entre múltiples hilos y procesos.

Cuestiones relacionadas