Métodos System.Threading.Monitor.Wait
Este artigo fornece observações complementares à documentação de referência para essa API.
Método Wait(Object, Int32, Boolean)
Esse método não retorna até que ele readquire um bloqueio exclusivo no obj
parâmetro.
O thread que atualmente possui o bloqueio no objeto especificado invoca esse método para liberar o objeto para que outro thread possa acessá-lo. O chamador é bloqueado enquanto aguarda para readquirir o bloqueio. Esse método é chamado quando o chamador precisa aguardar uma alteração de estado que ocorrerá como resultado das operações de outro thread.
O tempo limite garante que o thread atual não bloqueie indefinidamente se outro thread liberar o bloqueio sem primeiro chamar o Pulse método ou PulseAll . Ele também move o thread para a fila pronta, ignorando outros threads à sua frente na fila de espera, para que ele possa readquirir o bloqueio mais cedo. O thread pode testar o Wait valor de retorno do método para determinar se ele readquiriu o bloqueio antes do tempo limite. O thread pode avaliar as condições que fizeram com que ele entrasse na espera e, se necessário, chamar o Wait método novamente.
Quando um thread chama Wait
, ele libera o bloqueio e entra na fila de espera. Neste ponto, o próximo thread na fila pronta (se houver) tem permissão para assumir o controle do bloqueio. O thread que foi Wait
invocado permanece na fila de espera até que um thread que contém o bloqueio invoque , ou seja o próximo na fila e um thread que contenha o bloqueio invoquePulseAll.Pulse No entanto, se millisecondsTimeout
passar antes de Pulse outro thread invocar o método ou PulseAll esse objeto, o thread original será movido para a fila pronta para recuperar o bloqueio.
Observação
Se Infinite for especificado para o parâmetro, esse método será bloqueado indefinidamente, a menos que o millisecondsTimeout
detentor do bloqueio chame Pulse ou PulseAll. Se millisecondsTimeout
for igual a 0, o thread que chama Wait
libera o bloqueio e, em seguida, entra imediatamente na fila pronta para recuperar o bloqueio.
O chamador é Wait
executado uma vez, independentemente do número de vezes Enter que foi invocado para o objeto especificado. Conceitualmente, o método armazena o número de vezes que o chamador invocou Enter no objeto e invoca Exit quantas vezes forem necessárias para liberar totalmente o Wait
objeto bloqueado. Em seguida, o chamador bloqueia enquanto aguarda para readquirir o objeto. Quando o chamador readquire o bloqueio, o sistema chama Enter quantas vezes forem necessárias para restaurar a contagem salva Enter para o chamador. A chamada Wait
libera o bloqueio apenas para o objeto especificado, se o chamador for o proprietário de bloqueios em outros objetos, esses bloqueios não serão liberados.
Observação
Um objeto sincronizado contém várias referências, incluindo uma referência ao thread que atualmente contém o bloqueio, uma referência à fila pronta, que contém os threads que estão prontos para obter o bloqueio, e uma referência à fila de espera, que contém os threads que estão aguardando notificação de uma alteração no estado do objeto.
Os Pulsemétodos , PulseAlle Wait
devem ser invocados de dentro de um bloco sincronizado de código.
As observações para o método explicam o Pulse que acontece se Pulse for chamado quando nenhum thread está esperando.
Método Wait(Object, TimeSpan, Boolean)
Esse método não retorna até que ele readquire um bloqueio exclusivo no obj
parâmetro.
O thread que atualmente possui o bloqueio no objeto especificado invoca esse método para liberar o objeto para que outro thread possa acessá-lo. O chamador é bloqueado enquanto aguarda para readquirir o bloqueio. Esse método é chamado quando o chamador precisa aguardar uma alteração de estado que ocorrerá como resultado das operações de outro thread.
O tempo limite garante que o thread atual não bloqueie indefinidamente se outro thread liberar o bloqueio sem primeiro chamar o Pulse método ou PulseAll . Ele também move o thread para a fila pronta, ignorando outros threads à sua frente na fila de espera, para que ele possa readquirir o bloqueio mais cedo. O thread pode testar o Wait valor de retorno do método para determinar se ele readquiriu o bloqueio antes do tempo limite. O thread pode avaliar as condições que fizeram com que ele entrasse na espera e, se necessário, chamar o Wait método novamente.
Quando um thread chama Wait
, ele libera o bloqueio e entra na fila de espera. Neste ponto, o próximo thread na fila pronta (se houver) tem permissão para assumir o controle do bloqueio. O thread que foi Wait
invocado permanece na fila de espera até que um thread que contém o bloqueio invoque , ou seja o próximo na fila e um thread que contenha o bloqueio invoquePulseAll.Pulse No entanto, se timeout
milissegundos passarem antes de outro thread invocar o método ou PulseAll esse Pulse objeto, o thread original será movido para a fila pronta para recuperar o bloqueio.
Observação
Se um TimeSpan -1 milissegundo representativo for especificado para o parâmetro, esse método será bloqueado indefinidamente, a menos que o timeout
detentor do bloqueio chame Pulse ou PulseAll. Se timeout
for 0 milissegundos, o thread que chama Wait
libera o bloqueio e, em seguida, entra imediatamente na fila pronta para recuperar o bloqueio.
O chamador é Wait
executado uma vez, independentemente do número de vezes Enter que foi invocado para o objeto especificado. Conceitualmente, o método armazena o número de vezes que o chamador invocou Enter no objeto e invoca Exit quantas vezes forem necessárias para liberar totalmente o Wait
objeto bloqueado. Em seguida, o chamador bloqueia enquanto aguarda para readquirir o objeto. Quando o chamador readquire o bloqueio, o sistema chama Enter quantas vezes forem necessárias para restaurar a contagem salva Enter para o chamador. A chamada Wait
libera o bloqueio apenas para o objeto especificado, se o chamador for o proprietário de bloqueios em outros objetos, esses bloqueios não serão liberados.
Observação
Um objeto sincronizado contém várias referências, incluindo uma referência ao thread que atualmente contém o bloqueio, uma referência à fila pronta, que contém os threads que estão prontos para obter o bloqueio, e uma referência à fila de espera, que contém os threads que estão aguardando notificação de uma alteração no estado do objeto.
Os Pulsemétodos , PulseAlle Wait
devem ser invocados de dentro de um bloco sincronizado de código.
As observações para o método explicam o Pulse que acontece se Pulse for chamado quando nenhum thread está esperando.
Sair do contexto
OexitContext
parâmetro não tem efeito a menos que o Wait método seja chamado de dentro de um contexto gerenciado não padrão. Isso pode acontecer se o thread estiver dentro de uma chamada para uma instância de uma classe derivada do ContextBoundObject. Mesmo se você estiver executando um método em uma classe que não é derivada de , como String, você pode estar em um contexto não padrão se um ContextBoundObject estiver em sua pilha no domínio de ContextBoundObjectaplicativo atual.
Quando seu código está sendo executado em um contexto não padrão, especificar true
para exitContext
faz com que o thread saia do contexto gerenciado não padrão (ou seja, faça a transição para o contexto padrão) antes de executar o Wait método. Ele retorna ao contexto não padrão original após a conclusão da chamada para o Wait método.
Isso pode ser útil quando a classe vinculada ao contexto tem o SynchronizationAttribute atributo aplicado. Nesse caso, todas as chamadas para membros da classe são sincronizadas automaticamente e o domínio de sincronização é o corpo inteiro do código da classe. Se o código na pilha de chamadas de um membro chamar o método e especificar true
para , o Wait thread sairá do domínio de sincronização, permitindo que um thread bloqueado em uma chamada para exitContext
qualquer membro do objeto continue. Quando o método retorna, o thread que fez a chamada deve aguardar para reinserir o Wait domínio de sincronização.