Usando a instrução lock em um loop em C #
Vamos pegar a classe de amostra SomeThread, na qual estamos tentando impedir que os métodos DoSomething sejam chamados após a propriedade Running ser configurada como false e Dispose ser chamado pela classe OtherThread, porque se eles forem chamados após o método Dispose, o mundo terminará como nós Sei.
Parece que há uma chance de algo ruim acontecer por causa do loop. Que, no ponto em que inicia o próximo loop e antes que o bloqueio seja executado antes de chamar os métodos DoSomething, Running pode ser alterado para false e Disposed chamado antes de atingir o bloqueio. Nesse cenário, a vida não seria boa.
Eu estava procurando maneiras de lidar com isso ao usar um loop em um método simples e fácil de manter. Para o registro, considerei o Double Lock Check padronizado, no entanto, parece não ser recomendado para C #.
Aviso: Este é um exemplo simplificado para tentar facilitar o foco no problema com o loop e o bloqueio em um. Se eu não tiver elaborado o suficiente, informe-me e farei o possível para preencher todos os detalhes.
public class SomeThread : IDisposable
{
private object locker = new object();
private bool running = false;
public bool Running
{
get
{
lock(locker)
{
return running;
}
}
set
{
lock(locker)
{
running = value;
}
}
}
public void Run()
{
while (Running)
{
lock(locker)
{
DoSomething1();
DoSomething2();
}
}
}
private void DoSomething1()
{
// something awesome happens here
}
private void DoSomething2()
{
// something more awesome happens here
}
public void Dispose()
{
lock (locker)
{
Dispose1();
Dispose2();
}
}
private void Dispose1()
{
// something awesome happens here
}
private void Dispose2()
{
// something more awesome happens here
}
}
public class OtherThread
{
SomeThread st = new SomeThread();
public void OnQuit()
{
st.Running = false;
st.Dispose();
Exit();
}
}