Pergunta

De vez em quando recebo uma System.Threading.ThreadStateException ao tentar reiniciar um thread.O código em questão é o seguinte:

// Make sure the thread is done stopping
while (this.mThread.ThreadState == ThreadState.Running)
{ 
    Thread.Sleep(0);
}
// Respawn a thread if the current one is stopped or doesn't exist
if (this.mThread == null || this.mThread.ThreadState == ThreadState.Stopped)
{ 
    this.mThread = new Thread(new ParameterizedThreadStart(Monitor)); }
// Start the thread
if (check)
{ 
    this.mThread.Start(60000); 
}
else
{   
    this.mThread.Start(0); 
}

Portanto, duas perguntas: esta é a maneira correta de fazer as coisas e existe uma maneira de evitar que o erro ocorra?

Foi útil?

Solução

O problema é que você tem um código que primeiro verifica se deve criar um novo objeto de thread e outro trecho de código que determina se o objeto de thread deve ser iniciado.Devido a condições de corrida e coisas semelhantes, seu código pode acabar tentando chamar .Start em um objeto de thread existente.Considerando que você não publica os detalhes por trás do verificar variável, é impossível saber o que pode desencadear esse comportamento.

Você deve reorganizar seu código para que .Start seja chamado apenas em novos objetos.Resumindo, você deve colocar o método Start na mesma instrução if daquela que cria um novo objeto thread.

Pessoalmente, eu tentaria reorganizar todo o código para não precisar criar outro thread, mas agrupar o código dentro do objeto thread dentro de um loop para que o thread continue funcionando.

Outras dicas

É possível que um thread esteja em mais de um estado ao mesmo tempo, portanto a propriedade ThreadState é na verdade um bitmap de estados possíveis.Portanto, testar a igualdade com apenas um estado não lhe dará o resultado correto.Você precisaria fazer algo como:

if((mThread.ThreadState & ThreadState.Running) != 0)

No entanto, verificar o estado do thread é errado fazer qualquer coisa.Não estou totalmente claro o que você está tentando alcançar, mas acho que você está aguardando o término de um thread antes de reiniciá-lo.Nesse caso você deve fazer:

mThread.Join();
mThread = new Thread(new ParameterizedThreadStart(Monitor));
if(check)
    mThread.Start(60000);
else
    mThread.Start(0);

Embora se você descrever o problema que está tentando resolver com mais detalhes, tenho quase certeza de que haverá uma solução melhor.Esperar que um thread termine apenas para reiniciá-lo novamente não parece tão eficiente para mim.Talvez você só precise de algum tipo de comunicação entre threads?

John.

Uma ThreadStateException é lançada porque você está tentando iniciar um thread que não está em um estado inicializável.As situações mais prováveis ​​seriam que ele já estivesse em execução ou tivesse sido totalmente encerrado.

Existem potencialmente algumas coisas que podem estar acontecendo.Primeiro, o thread pode ter feito a transição de Running para StopRequested, que ainda não está totalmente parado, então sua lógica não cria um novo thread e você está tentando iniciar um thread que acabou de ser executado ou está prestes a ser executado. terminar a execução (nenhum dos quais é um estado válido para reiniciar).

A outra possibilidade é que o thread tenha sido abortado.Threads que são abortados vão para o estado Abortado, não para o estado Parado e, claro, também não são válidos para reinicialização.

Na verdade, o único tipo de thread que ainda está ativo e que pode ser “reiniciado” é aquele que está suspenso.Você pode querer usar esta condicional:

if (this.mThread == null || this.mThread.ThreadState != ThreadState.Suspended)

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