Por que (ou não) a configuração de campos em um construtor é segura para threads?

Digamos que você tenha uma classe simples como esta:

class MyClass
{
    private readonly int a;
    private int b;

    public MyClass(int a, int b) { this.a = a; this.b = b; }

    public int A { get { return a; } }
    public int B { get { return b; } }
}

Eu poderia usar esta classe de uma maneira multiencadeada:

MyClass value = null;
Task.Run(() => {
    while (true) { value = new MyClass(1, 1); Thread.Sleep(10); }
});
while (true)
{
    MyClass result = value;
    if (result != null && (result.A != 1 || result.B != 1)) { 
        throw new Exception(); 
    }
    Thread.Sleep(10);
}

Minha pergunta é: algum dia eu verei esse (ou outro código multithread similar) lançar uma exceção? Costumo ver referência ao fato de que gravações não voláteis podem não ser vistas imediatamente por outros threads. Portanto, parece que isso pode falhar porque a gravação no campo de valor pode ocorrer antes das gravações em a e b. Isso é possível ou existe algo no modelo de memória que torna esse padrão (bastante comum) seguro? Se assim for, o que é? O readonly é importante para esse fim? Importa se aeb são um tipo que não pode ser escrito atomicamente (por exemplo, uma estrutura personalizada)?

questionAnswers(6)

yourAnswerToTheQuestion