Mon application Web renvoie un fichier du système de fichiers. Ces fichiers sont dynamiques, donc je n'ai aucun moyen de connaître les noms o combien y en aura-t-il. Lorsque ce fichier n'existe pas, l'application le crée à partir de la base de données. Je veux éviter que deux threads différents recréent le même fichier en même temps, ou qu'un thread essaye de renvoyer le fichier pendant qu'un autre thread le crée.Comment verrouiller un fichier et éviter les lectures pendant l'écriture
De plus, je ne veux pas avoir de verrou sur un élément commun à tous les fichiers. Par conséquent, je devrais verrouiller le fichier juste quand je le crée. Donc je veux verrouiller un fichier jusqu'à ce que sa récréation soit terminée, si un autre thread essaye d'y accéder ... il devra attendre que le fichier soit déverrouillé.
J'ai lu sur FileStream.Lock, mais je dois connaître la longueur du fichier et cela n'empêchera pas cet autre thread d'essayer de lire le fichier, donc cela ne fonctionne pas dans mon cas particulier.
J'ai aussi lu sur FileShare.None, mais il va lancer une exception (quel type d'exception?) Si d'autres threads/processus essaient d'accéder au fichier ... donc je devrais développer un "try again while Faute "parce que je voudrais éviter la génération d'exception ... et je n'aime pas trop cette approche, bien que peut-être il n'y a pas de meilleure façon.
L'approche avec FileShare.None serait ce plus ou moins:
static void Main(string[] args)
{
new Thread(new ThreadStart(WriteFile)).Start();
Thread.Sleep(1000);
new Thread(new ThreadStart(ReadFile)).Start();
Console.ReadKey(true);
}
static void WriteFile()
{
using (FileStream fs = new FileStream("lala.txt", FileMode.Create, FileAccess.Write, FileShare.None))
using (StreamWriter sw = new StreamWriter(fs))
{
Thread.Sleep(3000);
sw.WriteLine("trolololoooooooooo lolololo");
}
}
static void ReadFile()
{
Boolean readed = false;
Int32 maxTries = 5;
while (!readed && maxTries > 0)
{
try
{
Console.WriteLine("Reading...");
using (FileStream fs = new FileStream("lala.txt", FileMode.Open, FileAccess.Read, FileShare.Read))
using (StreamReader sr = new StreamReader(fs))
{
while (!sr.EndOfStream)
Console.WriteLine(sr.ReadToEnd());
}
readed = true;
Console.WriteLine("Readed");
}
catch (IOException)
{
Console.WriteLine("Fail: " + maxTries.ToString());
maxTries--;
Thread.Sleep(1000);
}
}
}
Mais je n'aime pas le fait que je dois prendre des exceptions, essayez plusieurs fois et attendre une quantité inexacte de temps: |
Il s'agit de FileShare.None au lieu de FileAccess.None (FileAccess définit l'accès à votre application, tandis que FileShare est utilisé pour verrouiller le fichier, comme vous le souhaitez) – jpabluz
Sur un autre sujet, pensez à déverrouiller le fichier chaque fois que votre application est détruite , Je déteste quand le verrouillage reste après. – jpabluz
J'ai modifié et corrigé, merci! – vtortola