2010-05-18 2 views
3

Le code suivant est extrait du modèle (Windows Identity Foundation SDK) que MS utilise pour créer un nouveau site Web de service de jetons de sécurité.Comment lock (syncRoot) a-t-il un sens sur une méthode statique?

public static CustomSecurityTokenServiceConfiguration Current 
{ 
    get 
    { 
     var key = CustomSecurityTokenServiceConfigurationKey; 

     var httpAppState = HttpContext.Current.Application; 

     var customConfiguration = httpAppState.Get(key) 
      as CustomSecurityTokenServiceConfiguration; 

     if (customConfiguration == null) 
     { 
      lock (syncRoot) 
      { 
       customConfiguration = httpAppState.Get(key) 
        as CustomSecurityTokenServiceConfiguration; 

       if (customConfiguration == null) 
       { 
        customConfiguration = 
         new CustomSecurityTokenServiceConfiguration(); 
        httpAppState.Add(key, customConfiguration); 
       } 
      } 
     }  
     return customConfiguration; 
    } 
} 

Je suis relativement nouveau dans la programmation multi-thread. Je suppose que la raison de l'instruction lock est de rendre ce code thread-safe dans le cas où deux demandes Web arrivent sur le site Web en même temps.

Cependant, j'aurais pensé que l'utilisation de lock (syncRoot) n'aurait pas de sens car syncRoot fait référence à l'instance actuelle sur laquelle cette méthode opère ... mais c'est une méthode statique!

Comment cela a-t-il un sens?

+2

Où 'syncRoot' est-il défini? – Paolo

+0

@Paolo: C'est une bonne question. Cela dit, je suppose que c'est soit une variable 'static' ou retournée par un Singleton donné son nom. – Powerlord

+0

@Bemrose: L'hypothèse que j'ai faite est que 'syncRoot' est un champ de classe statique qui contient toujours la même instance:' private readonly object syncRoot = nouvel objet(); '. Bien sûr, 'syncRoot' pourrait être défini comme suit:' private object syncRoot {get {return new object(); }} '. Dans ce cas, nous serions en difficulté :-) – Steven

Répondre

6

L'instruction C# lock ne se verrouille pas sur une méthode, mais sur l'objet auquel elle est fournie. Dans votre cas syncRoot. Étant donné qu'il existe une seule instance de cet objet syncRoot, cela garantit que la classe CustomSecurityTokenServiceConfiguration ne sera créée qu'une seule fois pour ce domaine d'application. Ainsi, la propriété peut être appelée et exécutée en parallèle. Cependant, le bloc au sein du lock { ... } ne sera jamais appelé en parallèle. Cependant, il peut être appelé plusieurs fois et c'est ce que fait l'instruction supplémentaire if (customConfiguration == null) dans le bloc lock. Ce mécanisme est appelé un verrou à double vérification.

+0

OK. En regardant plus attentivement ce code, je vois que 'syncRoot' est déclaré comme un objet statique. J'étais juste un peu confus parce que je suis habitué à voir 'syncRoot' apparaître en tant que membre des classes d'énumération .net. Il semble que ce bloc de code soit le seul endroit où 'syncRoot' est utilisé, il doit donc avoir été déclaré dans le but exprès de verrouiller le bloc de code. –

+0

C'est la manière courante de faire le verrouillage en utilisant le mot-clé 'lock' dans .NET: Créez un' Object' privé en lecture seule et utilisez-le comme objet pour verrouiller. – Steven

Questions connexes