Question

Puis-je utiliser le constructeur de FileStream pour assurer un seul processus accède à un fichier à la fois? Est-ce que le travail de code suivant?

public static IDisposable AcquireFileLock() {
    IDisposable lockObj;
    do {
        // spinlock - continually try to open the file until we succeed
        lockObj = TryOpenLockFile();

        // sleep for a little bit to let someone else have a go if we fail
        if (lockObj == null) Thread.Sleep(100); 
    }
    while (lockObj == null);

    return lockObj;
}

private static FileStream TryOpenLockFile() {
    try {
        return new FileStream(s_LockFileName, FileMode.Create, FileAccess.Read, FileShare.None);
    }
    catch (IOException) {
        return null;
    }
}

En particulier, le comportement WRT atomique FileMode.Create autres processus? Y at-il autre chose que je devrais utiliser?

EDIT:. Pour être plus précis, c'est à l'aide de Microsoft CLR fichiers locaux sur une seule machine

Était-ce utile?

La solution

Cela va faire ce que vous voulez. FileShare.None est la partie importante.

Si toutes les applications sont écrivain sur le même ordinateur, vous pouvez également utiliser un mutex nommé pour atteindre le même objectif sans un fichier physique étant nécessaire, ou pour l'accès aux fichiers médiate si vous ne se soucient pas qui écrit dans le fichier dernier (juste que les écritures ne sont pas concurrentes). Cela pourrait vous éviter d'avoir à rouvrir le dossier à chaque fois, et fournir une place sémantique blocage de la boucle de Sleep (meilleure perf).

Notez que tout processus peut squatter votre fichier (Mutex) si le nom n'est pas traité comme un secret, à savoir l'information qui doit être conservées en toute sécurité.

Autres conseils

Cela fonctionne, compte tenu des mises en garde suivantes:

  • Vous êtes sous Windows (Linux via Mono, cela ne tient pas puisque les verrous de fichier sont de conseil, de sorte que votre méthode réussit toujours)
  • Vous accédez à un fichier local (SMB aussi probablement le travail, mais NFS ou WebDAV presque certainement pas)
  • Attraper IOException est probablement trop large, vous devez vérifier spécifiquement qu'il a échoué en raison d'une violation de partage
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top