exception soulevée dans le cas de l'accès aux fichiers en même temps que StreamReader

StackOverflow https://stackoverflow.com/questions/4324719

  •  29-09-2019
  •  | 
  •  

Question

J'ai trouvé un poste parler de gestion de fichiers en même temps l'accès à StreamWriter.

Le problème est que les réponses ne parviennent pas le scénario dans lequel le fichier est en cours d'accès, mais plusieurs processus.

Raconte-moi peu de temps:

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

Il y a un scénario connu concurrency, où plusieurs applications (processus) vont essayer d'écrire dans ce fichier. Cela peut être géré par une nouvelle tentative l'écriture après un court délai. Mais je ne veux pas nouvelle tentative si elle est ot une erreur de sécurité ou 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 élevé dans le cas de la concomitance writting. Je sais déjà 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 de poignée avec la concurrence du CIO + Mutex pour le processus en concurrence
  • Oui, je veux vraiment tout journal à écrire dans le même fichier
Était-ce utile?

La solution

Ce sera un IOException avec le texte:

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

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;
    }
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top