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();
    }
}

questionAnswers(3)

yourAnswerToTheQuestion