tag - que significa c#
palabra clave de bloqueo en C# (10)
¿Cuándo se debe usar la cerradura?
Se debe usar un bloqueo para proteger los recursos compartidos en código multiproceso. No para nada más.
¿Pero es necesario cuando la aplicación no genera ningún otro hilo?
Absolutamente no. Es solo una pérdida de tiempo. Sin embargo, asegúrese de no utilizar implícitamente los hilos del sistema. Por ejemplo, si usa E / S asíncrona, puede recibir devoluciones de llamada de un hilo aleatorio, no de su hilo original.
¿Hay problemas de rendimiento con el uso de bloqueo?
Sí. No son muy grandes en una aplicación de subproceso único, pero ¿por qué hacer llamadas que no necesita?
... si ese es un buen patrón de diseño a seguir en el futuro [?]
Bloquear todo lo que quiera o no es un patrón de diseño terrible. Si su código está desordenado con un bloqueo aleatorio y luego decide usar un hilo de fondo para algún trabajo, es probable que se encuentre con puntos muertos. Compartir un recurso entre varios hilos requiere un diseño cuidadoso, y cuanto más puedas aislar la parte difícil, mejor.
Entiendo la función principal de la palabra clave de bloqueo de MSDN
Declaración de bloqueo (Referencia C #)
La palabra clave de bloqueo marca un bloque de instrucciones como una sección crítica al obtener el bloqueo de exclusión mutua para un objeto determinado, ejecutar una instrucción y luego liberar el bloqueo.
¿Cuándo se debe usar la cerradura?
Por ejemplo, tiene sentido con aplicaciones de subprocesos múltiples porque protege los datos. ¿Pero es necesario cuando la aplicación no genera ningún otro hilo?
¿Hay problemas de rendimiento con el uso de bloqueo?
Acabo de heredar una aplicación que está usando el bloqueo en todas partes, y es de un solo hilo y quiero saber si debo dejarlos, ¿son necesarios?
Tenga en cuenta que esto es más una pregunta de conocimiento general, la velocidad de la aplicación es buena, quiero saber si ese es un buen patrón de diseño a seguir en el futuro o si debe evitarse a menos que sea absolutamente necesario.
En general, si su aplicación es de un solo hilo, no obtendrá mucho uso de la instrucción de bloqueo. Al no conocer su solicitud exactamente, no sé si son útiles o no, pero sospecho que no. Además, si su aplicación está utilizando el bloqueo en todas partes, no sé si sentiría toda la confianza de que funciona en un entorno de subprocesos múltiples de todos modos: ¿el desarrollador original realmente sabía cómo desarrollar código de subprocesos múltiples? simplemente agregan declaraciones de bloqueo en todas partes con la vaga esperanza de que eso sea suficiente.
Lock (token) solo se usa para marcar uno o más bloques de código que no deberían ejecutarse simultáneamente en múltiples hilos. Si su aplicación es de subproceso único, protege contra una condición que no puede existir.
Y el bloqueo invoca un golpe de rendimiento, agregando instrucciones para verificar el acceso simultáneo antes de que se ejecute el código. Solo debe usarse cuando sea necesario.
No tiene sentido tener bloqueos en la aplicación si solo hay un hilo y sí, es un golpe de rendimiento aunque requiere un buen número de llamadas para que ese golpe se acumule en algo significativo.
Puede tener problemas de rendimiento con las variables de bloqueo, pero normalmente, construiría su código para minimizar la cantidad de tiempo que pasan dentro de un bloque de código "bloqueado".
En cuanto a quitar las cerraduras. Dependerá de qué está haciendo exactamente el código. A pesar de que tiene un único hilo, si su objeto se implementa como Singleton, es posible que tenga varios clientes utilizando una instancia del mismo (en la memoria, en un servidor) al mismo tiempo.
Sí, habrá alguna penalización en el rendimiento cuando se usa el candado, pero generalmente es lo suficientemente negligente como para no importar.
El uso de bloqueos (o cualquier otra declaración o construcción de exclusión mutua) generalmente solo se necesita en escenarios de subprocesos múltiples en los que múltiples hilos (ya sea de su propia creación o de quien llama) tienen la oportunidad de interactuar con el objeto y cambiar el estado subyacente o datos mantenidos. Por ejemplo, si tiene una colección a la que se puede acceder mediante varios subprocesos, no quiere que un subproceso cambie el contenido de esa colección eliminando un elemento mientras otro subproceso intenta leerlo.
Tenga en cuenta que puede haber razones por las cuales su aplicación no es tan simple como usted piensa. Async I / O en .NET bien puede devolver la llamada en un hilo de grupo, por ejemplo, como lo hacen algunas de las diversas clases de temporizador (no el temporizador de Windows Forms).
Todas las respuestas aquí parecen correctas: la utilidad de las cerraduras es bloquear los hilos de un código bloqueado al mismo tiempo. Sin embargo, hay muchas sutilezas en este campo, una de las cuales es que los bloques bloqueados de código se marcan automáticamente como regiones críticas por Common Language Runtime.
El efecto del código que se marca como crítico es que, si la región completa no se puede ejecutar por completo, el tiempo de ejecución puede considerar que todo el dominio de la aplicación está potencialmente en peligro y, por lo tanto, descargarlo de la memoria. Para citar a MSDN :
Por ejemplo, considere una tarea que intenta asignar memoria mientras mantiene un bloqueo. Si la asignación de memoria falla, cancelar la tarea actual no es suficiente para garantizar la estabilidad del AppDomain, ya que puede haber otras tareas en el dominio esperando el mismo bloqueo. Si la tarea actual finaliza, otras tareas podrían estar en punto muerto.
Por lo tanto, aunque su aplicación sea de un solo hilo, esto puede ser un peligro para usted. Considere que un método en un bloque bloqueado arroja una excepción que eventualmente no se maneja dentro del bloque. Incluso si la excepción se reparte mientras sube la pila de llamadas, su región crítica de código no finalizó normalmente. ¿Y quién sabe cómo reaccionará el CLR?
Para obtener más información, lea este artículo sobre los peligros de Thread.Abort () .
se debe usar el bloqueo alrededor del código que modifica el estado compartido, estado que otros subprocesos modifican al mismo tiempo, y esas otras bandas deben tener el mismo bloqueo.
Un bloqueo es en realidad un serializador de acceso a memoria, los hilos (que llevan el bloqueo) esperarán en el bloqueo para entrar hasta que el hilo actual salga del bloqueo, por lo que el acceso a la memoria se serializará.
Para responder a su pregunta, el bloqueo no es necesario en una sola aplicación con subprocesos, y sí tiene efectos secundarios en el rendimiento. porque los bloqueos en C # se basan en objetos de sincronización del núcleo y cada bloqueo que realiza crea una transición al modo kernel desde el modo de usuario.
Si está interesado en el rendimiento de subprocesos múltiples, un buen punto de partida es MSDN Threading Guidelines.