usar programacion parametros metodos juegos hilos creación creacion con carrera c# multithreading optimization thread-safety

programacion - ¿Cuándo usar el hilo de bloqueo en C#?



programacion de hilos c# (5)

¿Es necesario el bloqueo cuando escribo solo para las variables a las que accede el público (listas C #) o incluso cuando leo de ellas?

Sí (incluso cuando lees).

¿Es necesario el bloqueo solo en los subprocesos asíncronos creados por el manejador de socket o en otros lugares también?

Sí. Siempre que el código acceda a una sección de código que se comparte, siempre se bloquea.

Esto parece que no está bloqueando objetos individuales , sino que bloquea una cosa para todas las situaciones de bloqueo.

Si es así, colóquelo en bloqueos inteligentes discretos creando objetos únicos individuales que relacionen y bloqueen solo ciertas secciones a la vez, que no interfieran con otros hilos en otras secciones.

Aquí hay un ejemplo:

// This class simulates the use of two different thread safe resources and how to lock them // for thread safety but not block other threads getting different resources. public class SmartLocking { private string StrResource1 { get; set; } private string StrResource2 { get; set; } private object _Lock1 = new object(); private object _Lock2 = new object(); public void DoWorkOn1( string change ) { lock (_Lock1) { _Resource1 = change; } } public void DoWorkOn2( string change2 ) { lock (_Lock2) { _Resource2 = change2; } } }

Tengo un servidor que maneja múltiples conexiones de socket entrantes y crea 2 hilos diferentes que almacenan los datos en formato XML.

Estaba usando la instrucción de lock para seguridad de hilos casi en cada controlador de eventos llamado asincrónicamente y en los 2 hilos en diferentes partes del código. Lamentablemente, utilizando este enfoque mi aplicación se ralentiza significativamente.

Traté de no usar ningún lock y el servidor se ejecuta muy rápido, incluso el almacenamiento de archivos parece aumentar; pero el programa se bloquea por razones que no entiendo después de 30 segundos - 1 minuto. de trabajo.

Asi que. Pensé que la mejor manera es usar menos bloqueos o usarlo solo allí donde sea estrictamente necesario. Como tal, tengo 2 preguntas:

  1. ¿Es necesario el bloqueo cuando escribo solo para las variables a las que accede el público (listas C #) o incluso cuando leo de ellas?

  2. ¿Es necesario el bloqueo solo en los subprocesos asíncronos creados por el manejador de socket o en otros lugares también?

Alguien podría darme algunas pautas prácticas sobre cómo operar. No publicaré todo el código esta vez. No tiene sentido publicar alrededor de 2500 líneas de código.


¿Alguna vez se ha sentado en su automóvil o en el autobús en una luz roja cuando no hay tráfico cruzado? Gran pérdida de tiempo, ¿verdad? Un candado es como un semáforo perfecto. Siempre es verde excepto cuando hay tráfico en la intersección.

Su pregunta es "Paso demasiado tiempo en el tráfico esperando las luces rojas. ¿Debo simplemente encender la luz roja? O mejor aún, ¿debo quitar las luces por completo y dejar que todos manejen a través de la intersección a velocidades de autopista sin ningún control de intersección? "

Si está teniendo un problema de rendimiento con los bloqueos, quitar los bloqueos es lo último que debe hacer. Usted está esperando en esa luz roja precisamente porque hay tráfico cruzado en la intersección . Los bloqueos son extraordinariamente rápidos si no se disputan.

No puedes eliminar la luz sin eliminar primero el tráfico cruzado. La mejor solución es, por lo tanto, eliminar el tráfico cruzado . Si nunca se disputa el candado, nunca lo esperarás. Descubre por qué el tráfico cruzado está pasando tanto tiempo en la intersección; no quite la luz y espero que no haya colisiones. Habrá.

Si no puede hacer eso, agregarle más bloqueos de grano fino a veces ayuda . Es decir, tal vez tengas todos los caminos de la ciudad convergiendo en la misma intersección. Quizás puedas dividir eso en dos intersecciones, de modo que el código se pueda mover a través de dos intersecciones diferentes al mismo tiempo.

Tenga en cuenta que hacer que los autos sean más rápidos (obtener un procesador más rápido) o acortar las carreteras (eliminando la longitud de la ruta del código) a menudo empeora el problema en escenarios de subprocesos múltiples. Tal como lo hace en la vida real; si el problema es un embotellamiento, comprar automóviles más rápidos y conducirlos en carreteras más cortas los lleva al atasco más rápido, pero no de manera más rápida.


Básicamente, esto se puede responder bastante simple:

Debe bloquear todas las cosas a las que acceden diferentes hilos. Realmente no importa si se trata de leer o escribir. Si está leyendo y otro hilo sobrescribe los datos al mismo tiempo, la lectura de datos puede no ser válida y es posible que esté realizando operaciones no válidas.


La razón por la que debe bloquear mientras lee es:

digamos que está realizando un cambio en una propiedad y se ha leído dos veces mientras el hilo está entre un bloqueo. Una vez antes de hacer cualquier cambio y otro después, tendremos resultados inconsistentes.

Espero que eso ayude,


Siempre use un candado cuando tenga acceso a miembros (ya sea de lectura o escritura). Si está iterando sobre una colección, y desde otra cadena está eliminando elementos, las cosas pueden salir mal rápidamente.

Una sugerencia es cuando desea iterar una colección, copiar todos los elementos en una nueva colección y luego repetir la copia. Es decir

var newcollection; // Initialize etc. lock(mycollection) { // Copy from mycollection to newcollection } foreach(var item in newcollection) { // Do stuff }

Del mismo modo, solo use el candado en el momento en que escribe en la lista.