Convención de nomenclatura para objetos de bloqueo de subprocesos dedicados [cerrado]

14

Una pregunta relativamente menor, pero no he podido encontrar la documentación oficial o incluso la opinión del blog / discusiones sobre ella.

En pocas palabras: cuando tengo un objeto privado cuyo único propósito es servir para el lock privado, ¿a qué llamo ese objeto?

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

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

¿Cómo deberíamos nombrar LockingObject aquí? También tenga en cuenta no solo el nombre de la variable, sino también su aspecto dentro del código cuando se bloquea.

He visto varios ejemplos, pero aparentemente no tengo un consejo sólido:

  1. Un montón de usos de SyncRoot (y variaciones tales como _syncRoot ).

    • Ejemplo de código: lock(SyncRoot) , lock(_syncRoot)
    • Esto parece estar influenciado por la declaración equivalente SyncLock de VB, la propiedad SyncRoot que existe en algunas de las clases de ICollection y parte de algún tipo de patrón de diseño de SyncRoot (lo que podría decirse que es una mala idea)
    • Al estar en un contexto de C #, no estoy seguro de si quisiera tener una denominación VBish. Peor aún, en VB nombrar la variable igual que la palabra clave. No estoy seguro de si esto sería una fuente de confusión o no.
  2. thisLock y lockThis de los artículos de MSDN: Declaración de bloqueo de C # , < a href="http://msdn.microsoft.com/en-us/library/3a86s51t.aspx"> Declaración de SyncLock de VB

    • Ejemplo de código: lock(thisLock) , lock(lockThis)
    • No estoy seguro si estos fueron nombrados mínimamente puramente para el ejemplo o no
    • Es un poco raro si estamos usando esto dentro de una clase / método static .
    • EDITAR: El artículo de Wikipedia sobre bloqueos también usa esta denominación para su ejemplo
  3. Varios usos de PadLock (de envoltura variable)

    • Ejemplo de código: lock(PadLock) , lock(padlock)
    • No está mal, pero mi única opción es que, como es lógico, invoca la imagen de un "candado" físico que tiendo a no asociar con el concepto abstracto de subprocesos .
  4. Nombrar el bloqueo en función de lo que pretende bloquear

    • Ejemplo de código: lock(messagesLock) , lock(DictionaryLock) , lock(commandQueueLock)
    • En el ejemplo de la página de VB SyncRoot MSDN, tiene un ejemplo simpleMessageList con un objeto privado messagesLock
    • No creo que sea una buena idea nombrar el bloqueo contra el tipo que está bloqueando ("DictionaryLock") ya que es un detalle de la implementación que puede cambiar. Prefiero nombrar alrededor del concepto / objeto que está bloqueando ("messagesLock" o "commandQueueLock")
    • Es interesante que muy rara vez veo esta convención de nomenclatura para bloquear objetos en muestras de código en línea o en StackOverflow.
  5. (EDITAR) La especificación de C # en la sección "8.12 The Lock Statement" tiene un ejemplo de este patrón y lo denomina synchronizationObject

    • Ejemplo de código: lock(SynchronizationObject) , lock(synchronizationObject)

Pregunta: ¿Cuál es su opinión en general acerca de nombrar privado para bloquear objetos?

Recientemente, comencé a nombrarlos ThreadLock (por lo que me gusta la opción 3), pero me estoy cuestionando ese nombre.

Con frecuencia estoy usando este patrón de bloqueo (en el ejemplo de código proporcionado anteriormente) en mis aplicaciones, así que pensé que podría tener sentido obtener una opinión / discusión más profesional acerca de una convención de nomenclatura sólida para ellos. Gracias!

    
pregunta Chris Sinclair 10.10.2012 - 17:33

3 respuestas

3

Tomé el hábito de llamarlo SomeResourceLock donde SomeResource es lo que necesita el bloqueo para acceder / actualizar, es decir (perdonar cualquier problema con el hilo, esto es solo una ilustración)

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
    }
}

Me he acostumbrado a este hábito después de tener clases en las que puedo tener varios bloqueos para diferentes recursos, por lo que nombro el objeto de bloqueo según los recursos a los que está bloqueando el acceso. A veces, un objeto puede estar bloqueando múltiples recursos, en cuyo caso trataría de hacer que los nombres respeten eso de alguna manera, por lo que el lector sabe que "otros bloqueos para esos recursos individuales también estarán en disputa con este bloqueo".

    
respondido por el Jimmy Hoffa 10.10.2012 - 18:09
5

Por lo general, lo llamo locker , pero como es privado, creo que es un detalle de implementación algo sin importancia. Primera regla de oro, use los estándares de su equipo / compañía. Si no hay uno, bueno, por favor haz uno y úsalo, pero al hacerlo, mantén las cosas simples. Si su clase tiene un solo objeto de bloqueo, llamarlo foo es suficiente. Si tiene muchos, un buen orden de negocios podría ser revisar el diseño de esa clase primero para ver si está haciendo demasiadas cosas diferentes. Pero, si no es así, entonces el nombre se vuelve importante, como en este ejemplo completamente diseñado:

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...
            }
        }
    }
}
    
respondido por el Jesse C. Slicer 10.10.2012 - 18:30
2

Siempre he usado lck_. De esa manera, si presionas ctrl + f 'lck', solo deberías encontrar los bloqueos, mientras que 'bloquear' también encontrará cosas como 'reloj'.

Cosas como lockThis y Padlock están bien para las carteras uni, pero para los proyectos adecuados, realmente debería usar nombres semánticos para que cuando vea las declaraciones sepa lo que realmente hace el objeto sin buscar en el código.

    
respondido por el Inverted Llama 10.10.2012 - 18:28

Lea otras preguntas en las etiquetas