2010-11-30 14 views
6

Hace unos meses estaba entrevistando para un trabajo dentro de la compañía en la que me encuentro actualmente, no tengo una sólida formación en desarrollo web, pero una de las preguntas que me hizo fue cómo podrías mejorar este bloque de códigoUsando 'Lock' en aplicaciones web

No recuerdo perfectamente el bloque de código, pero para resumir era un contador de visitas web, y usó el bloqueo en el contador de visitas.

lock(HitCounter) 
{ 
    // Bla... 
} 

Sin embargo, después de algunas discusiones, dijo, bloqueo es bueno, pero nunca lo use en aplicaciones web!

¿Cuál es la base de su declaración? ¿Por qué no debería usar el bloqueo en aplicaciones web?

+5

Aplicaciones web no son particularmente especiales, excepto tal vez que a menudo necesitan ser altamente concurrentes. Debe usar 'lock' cuando sea necesario, ni más ni menos, independientemente del tipo de aplicación. – LukeH

+0

¿HitCounter es una clase o una instancia? –

Respuesta

6

No hay ninguna razón especial por la cual los bloqueos no se deben usar en aplicaciones web.Sin embargo, deben usarse con cuidado, ya que son un mecanismo para serializar el acceso de subprocesos múltiples que puede causar el bloqueo si se disputan bloques de bloqueo. Sin embargo, esto no es solo una preocupación para las aplicaciones web.

Lo que siempre vale la pena recordar es que en el hardware moderno an uncontended lock takes 20 nanoseconds to flip. Con esto en mente, se debe seguir la práctica habitual de tratar de hacer que el código dentro de los bloqueos de bloqueo sea lo mínimo posible. Si tiene un código mínimo dentro de un bloque, la sobrecarga es bastante pequeña y el potencial de contención es bajo.

Decir que las cerraduras deben nunca ser usadas es realmente una declaración general. Realmente depende de cuáles son sus requisitos, p. una memoria caché en memoria sin hilos para ser compartida entre las solicitudes tendrá como resultado un menor bloqueo de solicitudes que la recuperación bajo demanda desde una base de datos.

Finalmente, los tipos de BCL y ASP.Net Framework ciertamente usan bloqueos internamente, por lo que indirectamente los está usando de todos modos.

6

El dominio de la aplicación puede ser reciclado.

Esto podría dar lugar a que el antiguo dominio de aplicación aún termine de atender algunas solicitudes y el nuevo dominio de aplicación también atienda nuevas solicitudes.

Las variables estáticas no se comparten entre ellas, por lo que el bloqueo en un global estático no otorgaría exclusividad en este caso.

0

Este código creará un cuello de botella para su aplicación ya que todas las solicitudes entrantes tendrán que esperar en este punto antes de que las anteriores salieran de la cerradura.

+1

todavía, esto no es específico para las aplicaciones web, ¿o sí? – xtofl

+0

@xtofl: esto no es específico de las aplicaciones web, pero la página es un punto de una aplicación web al que todos los usuarios tendrán acceso. Los bloqueos en otras aplicaciones se pueden usar con moderación y en áreas de bajo impacto. –

+1

Es específico de cualquier aplicación que use hilos separados para servir la solicitud entrante y donde pasará todo el hilo a través de este código. Las aplicaciones web son un buen ejemplo de eso. Lo es ? – VdesmedT

2

En primer lugar, nunca desea bloquear un objeto que realmente utiliza en cualquier aplicación. ¿Quieres crear un objeto de bloqueo y bloqueo que:

private readonly object _hitCounterLock = new object(); 
lock(_hitCounterLock) 
{ 
    //blah 
} 

En cuanto a la parte web de la cuestión, cuando se bloquea a bloquear todos los hilos que intenta acceder al objeto (que para la web podría ser cientos o miles de usuarios). Todos estarán esperando hasta que cada hilo delante de ellos se desbloquee.

+0

En segundo lugar, nunca debe bloquear una referencia que no sea de solo lectura. –

+0

Cierto también :-) Gracias por recordarme. Actualizando ahora. –

0

El bloqueo está diseñado solo para aplicaciones multiproceso donde varios subprocesos requieren acceso a la misma variable compartida, por lo tanto, un bloqueo es adquirido exclusivamente por el hilo solicitante y todos los hilos pendientes bloquearán y esperarán hasta que se libere el bloqueo.

en aplicaciones web, las peticiones del usuario están aislados lo que no hay necesidad de bloqueo por defecto

+0

Las aplicaciones web son definitivamente aplicaciones de múltiples hilos para permitir que se sirvan múltiples solicitudes simultáneamente. – VdesmedT

+0

parece que no entendiste el punto. Dije que las solicitudes están aisladas entre sí, lo que significa que, en el caso normal, no es necesario el bloqueo a menos que se utilicen variables de ámbito amplio compartidas o de aplicación. –

+0

Sí, no sé por qué las personas tienen problemas con ese concepto. La gente parece pensar que "no usar bloqueos en las aplicaciones web" significa que "las cerraduras en las aplicaciones web son malas". El punto es que casi nunca deberías tener una razón para usar bloqueos para empezar. Mi respuesta similar fue rechazada también. –

0

razones Pareja ...

  1. Si usted está tratando de bloquear una base de datos de operación de lectura/escritura , existe un riesgo muy alto de que una condición de carrera ocurra de todos modos porque la base de datos no es propiedad del proceso que hace el bloqueo, por lo que podría leerse/escribirse en otro proceso, tal vez incluso una versión futura hipotética de IIS que se ejecuta múltiples procesos por aplicación

  2. Los bloqueos se suelen utilizar en las aplicaciones cliente para subprocesos no UI, es decir, subprocesos de fondo/trabajo. Las aplicaciones web no son tan útiles para el procesamiento multiproceso, a menos que intente aprovechar varios núcleos (en cuyo caso, los bloqueos en los objetos asociados a la solicitud serían aceptables), ya que se puede suponer que cada solicitud se ejecuta en su propio hilo, y el servidor no puede responder hasta que se procese toda la salida (o al menos una secuencia chunk) de todos modos.

+0

El punto 1 podría aplicarse a cualquier dominio de aplicación, no solo a aplicaciones web, y de todos modos usaría una transacción aquí. –

+0

Las cerraduras de punto 2 no son específicas del dominio, por lo que no existe un uso de tipo de aplicación "típica". –

+0

1. Te estás perdiendo el punto. Las bases de datos normalmente viven en procesos separados. Podría usar una transacción, sí, pero esa es otra razón por la que no usaría un candado. 2. Te estás perdiendo el punto aquí también. En una aplicación de escritorio, el hilo del cliente debe ser receptivo, por lo que las operaciones pesadas se realizan de forma asincrónica. Ese no es el caso con las aplicaciones web, excepto cuando se encuentra en una situación en la que IO y CPU pueden funcionar por separado, en cuyo caso, de todos modos, no estaría utilizando un bloqueo. Al menos, no directamente. –

2

tarde :), pero para los futuros lectores de este, un punto adicional:

Si la aplicación se ejecuta en una granja de servidores web, de fórmula de la ASP en varias máquinas no compartirá el objeto de bloqueo

Así esto solo puede funcionar si 1. No se debe admitir granja web Y 2. ASP está configurado (no predeterminado) NO usar instancias paralelas durante el reciclaje hasta que se atiendan solicitudes antiguas (como se menciona en Andras)