Pergunta

Eu tenho um pouco de código, que eu não consigo descobrir corretamente. O problema é que o programa é multithreaded e dentro há um pouco de código que devem ser sincronizados então eu escrevi o seguinte:

lock (lockObject)
{
   if (!Monitor.TryEnter(lockObject))
     Monitor.Wait(lockObject);

   //do stuff...
   Monitor.PulseAll(lockObject);
}
Monitor.Exit(lockObject);

o problema que eu tenho é que em algum ponto no tempo os tópicos parecem estar dormindo - alguém pode dizer por quê? O programa continua a funcionar junto indefinidamente consome quase nenhum cpu, mas nenhum trabalho é feito - quando o rastreamento do programa que eu descobri que em algum ponto sem fio está ativa, mas um monte deles está dormindo. Eu sei que o erro maior parte (no caso de um desenvolvedor - sempre) fica 0.5m na frente do monitor -, mas não consigo descobrir sozinho ... talvez em poucos minutos;)

Alguém pode explicar isso para mim -. Obrigado antecipadamente

Foi útil?

Solução

Existe uma diferença entre LockObject e lockObject? Não está claro ...

No entanto! Se eles são diferentes objetos, em seguida, em primeiro lugar: você não pode Wait em um bloqueio que você não tem ... e TryEnter só retornará false se você especificar um tempo limite. O que exatamente é que o código está tentando fazer?

Sem mais contexto, não está totalmente claro o que o PulseAll e Wait são projetados para fazer; por exemplo, aqui eles são usados ??para bloquear a fila quando é muito cheio (Wait), ou liberá-lo quando o espaço se torna disponível (PulseAll), etc. é difícil depurar o código rosca sem as interações completas entre threads.

Parece que você só precisa:

lock (lockObject)
{
    // do stuff
}

Existem dois problemas imediatos que eu posso ver; em primeiro lugar, não é óbvio que você sempre liberar os bloqueios que você toma (ou seja, exceções). Tente lock uso apenas para o Enter/Exit -. Ele vai acertar

Em segundo lugar; se todo o Wait tópicos chamada ... quem vai acordá-los? O que eles estão esperando ? Conforme apresentado:. Sim, todos eles vão dormir indefinidamente

Outras dicas

Estou assming a primeira declaração de bloqueio é um erro de digitação e você significou bloqueio (LockObject) (em minúsculas).

Eu acho que você está mal-entendido bloqueia um pouco aqui. O bloco se em seu código nunca vai ser verdade. A razão é que lock (LockObject) realmente exapands para o seguinte

Monitor.Enter(lockObject);
try {
...
} finally{ 
Monitor.Exit(lockObject);

Assim, quando você acertar o bloco if você já possui o bloqueio e TryEnter deve sempre ter sucesso.

Essa é uma configuração estranha. 'LockObject' é o mesmo que 'LockObject'? Ou isso é um erro de digitação? Se eles são o mesmo, então a sua configuração é redundante, já que não há necessidade de chamar Monitor.TryEnter em algo que você já está travando. Se 'LockObject' é um objeto diferente, então por que não mover o Monitor.Exit para dentro da declaração de bloqueio?

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top