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

16

Una pregunta relativamente menor, pero no he podido encontrar documentación oficial ni siquiera opiniones de blog / debates sobre ella.

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

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

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

¿Qué deberíamos nombrar LockingObjectaquí? También considere no solo el nombre de la variable, sino también cómo se ve en el código cuando se bloquea.

He visto varios ejemplos, pero aparentemente no hay ningún consejo sólido:

  1. Muchos usos de SyncRoot(y variaciones como _syncRoot).

    • Código de ejemplo: lock(SyncRoot) ,lock(_syncRoot)
    • Esto parece estar influenciado por la SyncLockdeclaración equivalente de VB , la SyncRootpropiedad que existe en algunas de las clases de ICollection y parte de algún tipo de patrón de diseño de SyncRoot (que posiblemente sea una mala idea)
    • Al estar en un contexto C #, no estoy seguro de si me gustaría tener un nombre 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. thisLocky lockThisde los artículos de MSDN: Declaración de bloqueo de C # , Declaración de sincronización de VB

    • Código de ejemplo: lock(thisLock) ,lock(lockThis)
    • No estoy seguro si estos fueron nombrados mínimamente puramente para el ejemplo o no
    • Un poco extraño si estamos usando esto dentro de una staticclase / método.
    • EDITAR: el artículo de Wikipedia sobre cerraduras también utiliza este nombre para su ejemplo
  3. Varios usos de PadLock(de carcasa variable)

    • Código de ejemplo: lock(PadLock) ,lock(padlock)
    • No está mal, pero mi único problema es que, como era de esperar, invoca la imagen de un "candado" físico que tiendo a no asociar con el concepto abstracto de enhebrado .
  4. Nombrar el bloqueo en función de lo que pretende bloquear

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

    • Código de ejemplo: lock(SynchronizationObject) ,lock(synchronizationObject)

Pregunta: ¿Cuál es su opinión general acerca de nombrar objetos de bloqueo privados ?

Recientemente, comencé a nombrarlos ThreadLock(algo así como la opción 3), pero me encuentro cuestionando ese nombre.

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

Chris Sinclair
fuente

Respuestas:

4

He tomado la costumbre de llamarlo SomeResourceLockdonde SomeResourcees lo que necesita el bloqueo para acceder / actualizar, es decir (perdone cualquier problema de 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
    }
}

He encontrado este hábito después de tener clases en las que puedo tener múltiples bloqueos para diferentes recursos, así que llamo al objeto de bloqueo en función de a qué recursos 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, para que el lector sepa que "otros bloqueos para esos recursos individuales también estarán en conflicto con este bloqueo".

Jimmy Hoffa
fuente
2
Creo que esto es confuso, porque SynchronizationContextes algo bastante diferente.
svick
1
@svick Totalmente posible Estoy haciendo un mal uso del término, sigo pensando que es importante ser específico sobre el recurso que está bloqueado, pero si tiene más sentido, lo editaré para sugerir la palabra "Bloquear" en lugar de "SynchronizationContext".
Jimmy Hoffa
6

Normalmente lo llamo locker, pero como es privado, creo que es un detalle de implementación algo sin importancia. Primera regla general, use los estándares de su equipo / empresa. Si no hay uno, bueno, por favor haga uno y úselo, pero al hacerlo, mantenga las cosas simples. Si su clase tiene un único objeto de bloqueo, llamarlo fooes lo suficientemente bueno. Si tiene muchos, un buen orden del día podría ser simplemente revisar el diseño de esa clase primero para ver si está haciendo demasiadas cosas diferentes. Pero, si no, entonces el nombre se vuelve importante, como en este ejemplo completamente inventado:

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
fuente
2
Estoy totalmente de acuerdo con un estilo de denominación más o menos como este para múltiples mecanismos de bloqueo. Yo también tenía algo muy similar a este estilo cuando implementé una clase con dos casilleros (también lo refacté más tarde)
Chris Sinclair
2

Siempre usé lck_. De esa manera, si presiona Ctrl + f 'lck', entonces solo debe encontrar los bloqueos, mientras que 'lock' también encontrará cosas como 'clock'.

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 mire las declaraciones sepa lo que el objeto realmente hace sin buscar a través del código.

Llama invertida
fuente
No me gustan las formas cortas de nombres. Por un lado, tiene sentido tener un estilo de nombres único (ish) para encontrar todos los usos. Por otro lado, y tal vez he tenido suerte, no he tenido la necesidad de encontrar cerraduras; Me imagino que si tuviera que buscar "bloqueo" me daría un resultado suficientemente bueno con pocos falsos positivos suficientes para ignorar fácilmente.
Chris Sinclair