Convention de dénomination pour les objets de verrouillage de threads dédiés [fermé]

16

Une question relativement mineure, mais je n'ai pas pu trouver de documentation officielle ni même d'opinion de blog / discussions à ce sujet.

En termes simples: quand j'ai un objet privé dont le seul but est de servir à des fins privées lock, comment dois-je nommer cet objet?

class MyClass
{
    private object LockingObject = new object();

    void DoSomething()
    {
        lock(LockingObject)
        {
            //do something
        }
    }
}

Que devons-nous nommer LockingObjectici? Tenez également compte non seulement du nom de la variable, mais aussi de son aspect dans le code lors du verrouillage.

J'ai vu divers exemples, mais apparemment aucun bon conseil:

  1. Beaucoup d'utilisations de SyncRoot(et de variantes telles que _syncRoot).

    • Exemple de code: lock(SyncRoot) ,lock(_syncRoot)
    • Cela semble être influencé par la SyncLockdéclaration équivalente de VB , la SyncRootpropriété qui existe sur certaines des classes ICollection et une partie d'une sorte de modèle de conception SyncRoot (ce qui est sans doute une mauvaise idée)
    • Étant dans un contexte C #, je ne sais pas si je voudrais avoir un nom VBish. Pire encore, en VB, nommer la variable de la même manière que le mot-clé. Je ne sais pas si cela serait une source de confusion ou non.
  2. thisLocket lockThisdes articles MSDN: C # verrou Déclaration , VB SyncLock Déclaration

    • Exemple de code: lock(thisLock) ,lock(lockThis)
    • Je ne sais pas si ceux-ci ont été nommés de manière minimale uniquement pour l'exemple ou non
    • Un peu bizarre si nous utilisons cela dans une staticclasse / méthode.
    • EDIT: l'article Wikipedia sur les serrures utilise également cette dénomination pour son exemple
  3. Plusieurs utilisations de PadLock(de boîtier variable)

    • Exemple de code: lock(PadLock) ,lock(padlock)
    • Pas mal, mais mon seul bœuf est qu'il invoque sans surprise l'image d'un "cadenas" physique que j'ai tendance à ne pas associer au concept de filetage abstrait .
  4. Nommer le verrou en fonction de ce qu'il a l'intention de verrouiller

    • Exemple de code: lock(messagesLock) , lock(DictionaryLock),lock(commandQueueLock)
    • Dans l'exemple de page VB SyncRoot MSDN, il contient un simpleMessageListexemple avec un messagesLockobjet privé
    • Je ne pense pas que ce soit une bonne idée de nommer le verrou par rapport au type que vous verrouillez ("DictionaryLock") car c'est un détail d'implémentation qui peut changer. Je préfère nommer le concept / objet que vous verrouillez ("messagesLock" ou "commandQueueLock")
    • Fait intéressant, je vois très rarement cette convention de dénomination pour verrouiller des objets dans des exemples de code en ligne ou sur StackOverflow.
  5. (EDIT) La spécification C # dans la section "8.12 The Lock Statement" a un exemple de ce modèle et le nomme synchronizationObject

    • Exemple de code: lock(SynchronizationObject) ,lock(synchronizationObject)

Question: Que pensez-vous généralement de la dénomination des objets de verrouillage privés ?

Récemment, j'ai commencé à les nommer ThreadLock(donc un peu comme l'option 3), mais je me retrouve à remettre en question ce nom.

J'utilise fréquemment ce modèle de verrouillage (dans l'exemple de code fourni ci-dessus) dans mes applications, j'ai donc pensé qu'il pourrait être judicieux d'obtenir une opinion / discussion plus professionnelle sur une convention de dénomination solide pour eux. Merci!

Chris Sinclair
la source

Réponses:

4

J'ai pris l'habitude de l'appeler là SomeResourceLockSomeResourcevous avez besoin du verrou pour accéder / mettre à jour, c'est-à-dire (pardonnez tout problème de thread, ce n'est qu'une illustration)

public class ProcessDataInQueue
{
    private static Queue<Data> _dataQueue = new Queue<Data>();
    private static object _dataQueueLock = new Object();

    public void AddOneItem(Data itemToAdd)
    {
        lock(_dataQueueLock)
        {
            _dataQueue.Enqueue(itemToAdd);
        }
    }

    public void ProcessOneItem()
    {
        Data itemToProcess = null;
        lock(_dataQueueLock)
        {
            itemToProcess = _dataQueue.Dequeue();
        }
        // ... process itemToProcess
    }
}

Je suis tombé sur cette habitude après avoir eu des classes où je peux avoir plusieurs verrous pour différentes ressources, donc je nomme l'objet de verrouillage en fonction des ressources auxquelles il verrouille l'accès. Parfois, un objet peut verrouiller plusieurs ressources, auquel cas j'essayerais de faire respecter les noms d'une certaine manière, de sorte que le lecteur sait que "d'autres verrous pour ces ressources individuelles seront également en conflit avec ce verrou".

Jimmy Hoffa
la source
2
Je pense que cela prête à confusion, car SynchronizationContextc'est quelque chose de très différent.
svick
1
@svick Totalement possible J'utilise le terme à mauvais escient, je pense toujours qu'il est important d'être précis sur la ressource verrouillée mais si cela a plus de sens, je vais le modifier pour suggérer le mot "Lock" à la place de "SynchronizationContext".
Jimmy Hoffa
6

Je l'appelle habituellement locker, mais comme c'est privé, je pense que c'est un détail d'implémentation quelque peu insignifiant. Première règle d'or, utilisez les normes de votre équipe / entreprise. S'il n'y en a pas, bien, s'il vous plaît faire un et de l' utiliser, mais pour y parvenir, gardez -les simples choses. Si votre classe a un seul objet de verrouillage, l'appeler fooest suffisant. Si vous en avez plusieurs, un bon ordre du jour pourrait être de revoir d'abord le design de cette classe pour voir s'il fait trop de choses différentes. Mais, sinon, le nom devient important, comme dans cet exemple complètement artificiel:

public sealed class CustomerOrders
{
    private readonly object customerLocker = new object();

    private readonly object orderLocker = new object();

    public IEnumerable<Customer> Customers
    {
        get
        {
            lock (this.cutomerLocker)
            lock (this.orderLocker)
            {
                // stuff...
            }
        }

        set
        {
            lock (this.cutomerLocker)
            lock (this.orderLocker)
            {
                // other stuff...
            }
        }
    }

    public IEnumerable<Order> Orders
    {
        get
        {
            lock (this.orderLocker)
            {
                // stuff...
            }
        }

        set
        {
            lock (this.cutomerLocker)
            {
                // different stuff...
            }
        }
    }
}
Jesse C. Slicer
la source
2
Je suis totalement d'accord avec un style de dénomination plus ou moins comme celui-ci pour plusieurs mécanismes de verrouillage. Moi aussi, j'avais quelque chose de très similaire à ce style lorsque j'ai implémenté une classe avec deux casiers (également refactorisé plus tard)
Chris Sinclair
2

J'ai toujours utilisé lck_. De cette façon, si vous ctrl + f 'lck', vous ne devriez trouver que les verrous tandis que 'lock' trouvera également des choses comme 'horloge'.

Des choses comme lockThis et Padlock conviennent parfaitement aux portefeuilles uni, mais pour les projets appropriés, vous devez vraiment utiliser des noms sémantiques de sorte que lorsque vous regardez les déclarations, vous savez ce que fait réellement l'objet sans chercher dans le code.

Lama inversé
la source
Je n'aime pas les noms courts. D'une part, il est logique d'avoir un style de nommage unique (ish) pour trouver toutes les utilisations. D'un autre côté, et j'ai peut-être eu de la chance, je n'ai pas eu besoin de trouver de serrures; J'imagine que si je devais chercher "lock (") me donnerait un résultat assez bon avec assez peu de faux positifs à ignorer facilement.
Chris Sinclair