2010-12-01 2 views
3

J'ai trouvé un post talking about handling concurrent file access with StreamWriter.Exception levée dans le cas d'un accès concurrent aux fichiers avec StreamReader

Le problème est que les réponses ne gèrent pas le scénario d'accès au fichier mais plusieurs processus.

Raconte-moi peu de temps:

  • J'ai plusieurs applications
  • je besoin d'un système d'enregistrement centralisé dans la base
  • Si la base de données échoue, je besoin d'un repli sur un journal du système de fichiers

Il existe un scénario de concurrence connu, dans lequel plusieurs applications (processus) essaieront d'écrire dans ce fichier. Cela peut être géré en réessayant l'écriture après un court délai. Mais je ne veux pas reattempt s'il s'agit d'une erreur de sécurité ou d'une erreur de syntaxe de nom de fichier.

Le code est ici:

// true if an access error occured 
bool accessError = false; 
// number fo writing attemps 
int attempts = 0; 

do 
{ 
    try 
    { 
     // open the file 
     using (StreamWriter file = new StreamWriter(filename, true)) 
     { 
      // write the line 
      file.WriteLine(log); 
      // success 
      result = true; 
     } 
    } 
     /////////////// access errors /////////////// 
    catch (ArgumentException) 
    { 
     accessError = true; 
    } 
    catch (DirectoryNotFoundException) 
    { 
     accessError = true; 
    } 
    catch (PathTooLongException) 
    { 
     accessError = true; 
    } 
    catch (SecurityException) 
    { 
     accessError = true; 
    } 
     /////////////// concurrent writing errors /////////////// 
    catch (Exception) 
    { 
     // WHAT EXCEPTION SHOULD I CATCH HERE ? 
     // sleep before retrying 
     Thread.Sleep(ConcurrentWriteDelay); 
    } 
    finally 
    { 
     attempts++; 
    } 
    // while the number of attemps has not been reached 
} while ((attempts < ConcurrentWriteAttempts) 
      // while we have no access error 
      && !accessError 
      // while the log is not written 
      && !result); 

Ma seule question est le type d'exception qui sera soulevée dans le cas de la concurrence writting. Je sais déjà que les choses peuvent être faites différemment. Permettez-moi d'ajouter quelques considérations:

  • Non, je ne veux pas utiliser NLog dans ce scénario
  • Oui je avec la COI poignée + concurrency Mutex pour le processus en concurrence
  • Oui Je veux vraiment tout journal à écrire dans le même fichier

Répondre

2

ce sera un IOException avec le texte:

« le processus ne peut pas accéder au fichier « {0} » car il est utilisé par un autre proc ess. "

Ceci est une approche simpliste:

static bool LogError(string filename, string log) 
    { 
     const int MAX_RETRY = 10; 
     const int DELAY_MS = 1000; // 1 second 
     bool result = false; 
     int retry = 0; 
     bool keepRetry = true; 
     while (keepRetry && !result && retry < MAX_RETRY) 
     { 
      try 
      { 
       using (StreamWriter file = new StreamWriter(filename, true)) 
       { 
        // write the line 
        file.WriteLine(log); 
        // success 
        result = true; 
       } 
      } 
      catch (IOException ioException) 
      { 
       Thread.Sleep(DELAY_MS); 
       retry++; 
      } 
      catch (Exception e) 
      { 

       keepRetry = false; 
      } 

     } 
     return result; 
    } 
+0

Thxs pour la réponse, très intéressé par la source! – Mose

+0

Bien sûr! Je vais le mettre dans une minute ... – Aliostad

+0

Oh je voulais dire la source de l'information ^^ Mais un extrait est cool aussi pour les utilisateurs intéressés (le mien était un peu trop long) – Mose

Questions connexes