2010-10-24 6 views
18

J'ai une application multi-thread qui écrit dans un fichier xml de paramètres en utilisant une méthode statique. Je veux éviter que le fichier soit mis à jour deux fois en même temps (provoquant des accès/exception d'écriture).Lock() dans une méthode statique

Comment puis-je faire cela?

Cela ne fonctionne pas:

namespace Program 
{ 
    public class Settings 
    { 
     private static void SetSettingsValue (string settings, string value) 
     { 
      // make this thread safe to avoid writing to a locked settings xml file 
      lock (typeof(Settings)) 
      { 
       //write data to xml file 
      } 
     } 
    } 
} 
+1

Est-ce que vous disposez de votre fichier XML correctement (c'est-à-dire via 'using')? Pouvez-vous partager plus de code? En outre, pour les méthodes statiques, vous devez verrouiller les objets statiques privés, pas sur un type. Voir http://msdn.microsoft.com/en-us/library/c5kehkcz.aspx –

Répondre

33

Le concept de lock() est d'utiliser un objet existant qu'il peut référencer et utiliser pour contrôler si l'accès est accordé.

static object SpinLock = new object(); 

lock(SpinLock) 
{ 
    //Statements 
} 

Lorsque l'exécution quitte le verrou() bloquer la référence est libérée et les autres fils en attente d'exécution du bloc de code peut passer (une à la fois, bien sûr).

+2

Notez que vous ne pouvez pas modifier la référence SpinLock dans l'instruction lock() elle-même. L'objet utilisé pour le verrouillage doit être accessible à tous les threads qui doivent exécuter le code et ne peut pas changer de référence à chaque fois, sinon les threads ne se bloqueront jamais et vous aurez des conflits/conflits de ressources. –

37

Vous devez créer une procédure distincte, objet de verrouillage statique et utiliser. N'UTILISEZ PAS UNE CHAÎNE! Les chaînes sont automatiquement internées et il n'y aura qu'une seule instance de chaque chaîne déclarée par programme. Vous ne pouvez donc pas garantir un accès exclusif au verrou.

Vous devriez faire ceci:

public class A { 
    private static Object LOCK = new Object(); 

    private static void foo() { 
     lock(LOCK) { 
      // Do whatever 
     } 
    } 
} 

(La syntaxe peut être incorrecte, je suis une personne de Java la plupart du temps, mais les mêmes règles sur le verrouillage et chaîne interner appliquent à C#)

Le mot-clé de verrouillage applique un verrou d'exclusion mutuelle: un seul thread peut verrouiller un objet particulier à la fois. Si un deuxième thread appelle foo, il bloquera jusqu'à ce que le premier thread ait quitté le bloc de verrouillage.

Messages à emporter: pour un verrouillage de méthode statique sur une variable statique privée. Ne pas verrouiller sur Strings ou typeof (...) car vous ne pouvez pas garantir que personne d'autre n'utilise cet objet. Toujours verrouiller sur un objet que vous connaissez n'est pas touché par quelqu'un d'autre en le rendant privé et en le rendant nouveau.

+3

Ceci est la meilleure réponse dans toute la discussion. Parce que Cameron était assez sage pour spécifier que le verrou est privé à la classe. –

+0

Cela devrait aussi être quel que soit l'équivalent en C# de 'final', mais je ne suis pas un C# alors je ne suis pas sûr de ce que c'est. Si C# a C++ - style 'const' alors je pense que je vais passer de Java :) –

+0

Devinez pas: http://stackoverflow.com/questions/55984/what-is-the-difference-between-const-and- readonly –

Questions connexes