Saltar al contenido

Mejores prácticas al usar la declaración de bloqueo

El objeto que elija usar con la declaración de bloqueo no tiene mucho que ver, por lo que puede ser tentador bloquear algún objeto preexistente que tenga a su disposición. Por ejemplo, digamos que estás escribiendo una aplicación de consola de rastreo web multihilo y que tu aplicación tiene un búfer de un solo botón de algún tipo que representa un búfer de los datos que vas a escribir en un archivo.

123456publicclassCustomBuffer{...}publicstaticclassSingletons{publicstaticCustomBuffer LinksBuffer {get;privateset;}=...}

csharp

Mejores prácticas al usar la declaración de bloqueo
Mejores prácticas al usar la declaración de bloqueo

Cuando escribes el búfer en un archivo, necesitas sincronizar el acceso al archivo; por lo tanto, decides usar el bloqueo. En este contexto podría ser tentador bloquear el objeto de la memoria intermedia de un solo botón, por ejemplo:

1234567estáticoevitarEscribir EnlacesBufferParaArchivo(){lock(Singletons.LinksBuffer){...}}

csharp

Ahora, esto podría funcionar inicialmente y tiene la ventaja de que no tienes que crear una variable separada sólo para la cerradura. Pero digamos que más tarde aparece otro desarrollador que está trabajando en un aspecto completamente diferente de la aplicación. Este desarrollador es quizás menos concienzudo que usted, así que cuando necesitan bloquear, utilizan lo primero que encuentran. Digamos que ellos también eligen bloquear el mismo singleton de LinksBuffer, aunque lo que están sincronizando no tiene nada que ver con los enlaces. ¿Puedes ver por qué eso causaría un problema potencial?

Como resultado de la decisión del segundo desarrollador de fijar el mismo objeto, ahora tenemos un código no relacionado esperándonos. Se ha introducido inadvertidamente una ineficiencia (y quizás un error difícil de solucionar). Tal problema podría evitarse fácilmente si cada desarrollador creara su propio objeto para bloquearlo.

Consideremos otro ejemplo aún más insidioso. Digamos que te deshaces por completo de la clase Singletons e instanciar un CustomBuffer en tu código de rastreo web que está escribiendo enlaces a un archivo. Declaras el CustomBuffer como privado, así que crees que es seguro bloquear tu instancia de CustomBuffer porque ningún otro código tendrá acceso a él. Supongamos también que la clase CustomBuffer ahora vive en un ensamblaje separado y no tienes acceso al código fuente. Y, sin que lo sepas, en algún lugar dentro de CustomBuffer está el siguiente trozo de código:

1234lock(this){...}

csharp

Ahora, inadvertidamente, tenemos exactamente el mismo problema que antes: áreas no relacionadas de la aplicación están usando el mismo objeto para el bloqueo! Eso es porque esta instancia es accesible públicamente, como mínimo al declarante (su código de rastreo web en este caso). Por esa razón, deberías evitar bloquearla, a pesar de su casi irresistible conveniencia. Además, evita bloquear cualquier objeto que haga literalmente otra cosa que no sea bloquear. Hacerlo es la única manera de garantizar que no se introduzcan problemas como los anteriores. Con razón, el bloqueo de una variable de tipo de objeto dedicada y privada llamada myLocker o algo por el estilo se considera una buena práctica. El uso del objeto es entonces inequívoco y es poco probable que usted y otros desarrolladores lo utilicen accidentalmente en el futuro. Manténgalo simple! El siguiente enfoque es altamente recomendado y comúnmente usado. Utilice una variable de este tipo sólo para el bloqueo.

1privatestaticobject myLocker =newobject();

csharp