Métodos System.Threading.Monitor.Wait
En este artículo se proporcionan comentarios adicionales a la documentación de referencia de esta API.
Método Wait(Object, Int32, Boolean)
Este método no devuelve hasta que vuelve a adquirir un bloqueo exclusivo en el obj
parámetro .
El subproceso que posee actualmente el bloqueo en el objeto especificado invoca este método para liberar el objeto para que otro subproceso pueda acceder a él. El autor de la llamada se bloquea mientras espera a volver a adquirir el bloqueo. Se llama a este método cuando el autor de la llamada necesita esperar un cambio de estado que se producirá como resultado de las operaciones de otro subproceso.
El tiempo de espera garantiza que el subproceso actual no se bloquee indefinidamente si otro subproceso libera el bloqueo sin llamar primero al Pulse método o PulseAll . También mueve el subproceso a la cola lista, pasando otros subprocesos por delante de él en la cola de espera, de modo que pueda volver a adquirir el bloqueo antes. El subproceso puede probar el valor devuelto del Wait método para determinar si ha vuelto a adquirir el bloqueo antes del tiempo de espera. El subproceso puede evaluar las condiciones que provocaron que entrara en la espera y, si es necesario, llame al Wait método de nuevo.
Cuando un subproceso llama a Wait
, libera el bloqueo y entra en la cola en espera. En este punto, el siguiente subproceso de la cola lista (si hay uno) puede tomar el control del bloqueo. El subproceso invocado Wait
permanece en la cola en espera hasta que un subproceso PulseAllque contiene el bloqueo invoca o es el siguiente en la cola y un subproceso Pulseque contiene el bloqueo invoca . Sin embargo, si millisecondsTimeout
transcurre antes de que otro subproceso invoque el método o PulseAll el Pulse objeto, el subproceso original se mueve a la cola lista para recuperar el bloqueo.
Nota:
Si Infinite se especifica para el millisecondsTimeout
parámetro , este método se bloquea indefinidamente a menos que el titular del bloqueo llame a Pulse o PulseAll. Si millisecondsTimeout
es igual a 0, el subproceso que llama libera Wait
el bloqueo y, a continuación, entra inmediatamente en la cola lista para recuperar el bloqueo.
El autor de la llamada se Wait
ejecuta una vez, independientemente del número de veces Enter que se haya invocado para el objeto especificado. Conceptualmente, el Wait
método almacena el número de veces que el autor de la llamada invoca en Enter el objeto e invoca tantas Exit veces como sea necesario para liberar completamente el objeto bloqueado. A continuación, el autor de la llamada se bloquea mientras espera a volver a adquirir el objeto. Cuando el autor de la llamada vuelve a adquirir el bloqueo, el sistema llama tantas Enter veces como sea necesario para restaurar el recuento guardado Enter del autor de la llamada. La llamada Wait
a libera el bloqueo solo para el objeto especificado; si el autor de la llamada es el propietario de bloqueos en otros objetos, estos bloqueos no se liberan.
Nota:
Un objeto sincronizado contiene varias referencias, incluida una referencia al subproceso que contiene actualmente el bloqueo, una referencia a la cola lista, que contiene los subprocesos que están listos para obtener el bloqueo y una referencia a la cola en espera, que contiene los subprocesos que esperan la notificación de un cambio en el estado del objeto.
Los Pulsemétodos , PulseAlly Wait
se deben invocar desde dentro de un bloque de código sincronizado.
Los comentarios del Pulse método explican lo que sucede si se llama cuando Pulse no hay subprocesos en espera.
Método Wait(Object, TimeSpan, Boolean)
Este método no devuelve hasta que vuelve a adquirir un bloqueo exclusivo en el obj
parámetro .
El subproceso que posee actualmente el bloqueo en el objeto especificado invoca este método para liberar el objeto para que otro subproceso pueda acceder a él. El autor de la llamada se bloquea mientras espera a volver a adquirir el bloqueo. Se llama a este método cuando el autor de la llamada necesita esperar un cambio de estado que se producirá como resultado de las operaciones de otro subproceso.
El tiempo de espera garantiza que el subproceso actual no se bloquee indefinidamente si otro subproceso libera el bloqueo sin llamar primero al Pulse método o PulseAll . También mueve el subproceso a la cola lista, pasando otros subprocesos por delante de él en la cola de espera, de modo que pueda volver a adquirir el bloqueo antes. El subproceso puede probar el valor devuelto del Wait método para determinar si ha vuelto a adquirir el bloqueo antes del tiempo de espera. El subproceso puede evaluar las condiciones que provocaron que entrara en la espera y, si es necesario, llame al Wait método de nuevo.
Cuando un subproceso llama a Wait
, libera el bloqueo y entra en la cola en espera. En este punto, el siguiente subproceso de la cola lista (si hay uno) puede tomar el control del bloqueo. El subproceso invocado Wait
permanece en la cola en espera hasta que un subproceso PulseAllque contiene el bloqueo invoca o es el siguiente en la cola y un subproceso Pulseque contiene el bloqueo invoca . Sin embargo, si timeout
transcurren milisegundos antes de que otro subproceso invoque el método o PulseAll el Pulse objeto, el subproceso original se mueve a la cola lista para recuperar el bloqueo.
Nota:
Si se especifica un TimeSpan objeto que representa -1 milisegundos para el timeout
parámetro , este método se bloquea indefinidamente a menos que el titular del bloqueo llame a Pulse o PulseAll. Si timeout
es de 0 milisegundos, el subproceso que llama libera Wait
el bloqueo y, a continuación, entra inmediatamente en la cola lista para recuperar el bloqueo.
El autor de la llamada se Wait
ejecuta una vez, independientemente del número de veces Enter que se haya invocado para el objeto especificado. Conceptualmente, el Wait
método almacena el número de veces que el autor de la llamada invoca en Enter el objeto e invoca tantas Exit veces como sea necesario para liberar completamente el objeto bloqueado. A continuación, el autor de la llamada se bloquea mientras espera a volver a adquirir el objeto. Cuando el autor de la llamada vuelve a adquirir el bloqueo, el sistema llama tantas Enter veces como sea necesario para restaurar el recuento guardado Enter del autor de la llamada. La llamada Wait
a libera el bloqueo solo para el objeto especificado; si el autor de la llamada es el propietario de bloqueos en otros objetos, estos bloqueos no se liberan.
Nota:
Un objeto sincronizado contiene varias referencias, incluida una referencia al subproceso que contiene actualmente el bloqueo, una referencia a la cola lista, que contiene los subprocesos que están listos para obtener el bloqueo y una referencia a la cola en espera, que contiene los subprocesos que esperan la notificación de un cambio en el estado del objeto.
Los Pulsemétodos , PulseAlly Wait
se deben invocar desde dentro de un bloque de código sincronizado.
Los comentarios del Pulse método explican lo que sucede si se llama cuando Pulse no hay subprocesos en espera.
Salir del contexto
ElexitContext
parámetro no tiene ningún efecto a menos que se llame al Wait método desde dentro de un contexto administrado no predeterminado. Esto puede ocurrir si el subproceso está dentro de una llamada a una instancia de una clase derivada de ContextBoundObject. Incluso si actualmente está ejecutando un método en una clase que no se deriva de ContextBoundObject, como String, puede estar en un contexto no predeterminado si ContextBoundObject se encuentra en la pila en el dominio de aplicación actual.
Cuando el código se ejecuta en un contexto no predeterminado, especificar true
para exitContext
hace que el subproceso salga del contexto administrado no predeterminado (es decir, para realizar la transición al contexto predeterminado) antes de ejecutar el Wait método. Devuelve al contexto no predeterminado original una vez completada la llamada al Wait método .
Esto puede ser útil cuando la clase enlazada al contexto tiene aplicado el SynchronizationAttribute atributo . En ese caso, todas las llamadas a los miembros de la clase se sincronizan automáticamente y el dominio de sincronización es todo el cuerpo de código de la clase. Si el código de la pila de llamadas de un miembro llama al Wait método y especifica para exitContext
, el subproceso true
sale del dominio de sincronización, lo que permite que un subproceso bloqueado en una llamada a cualquier miembro del objeto continúe. Cuando el método vuelve, el Wait subproceso que realizó la llamada debe esperar a volver a escribir el dominio de sincronización.