It won't crash, but it might give the wrong results.
To block, you need to make sure that every access is protected via a lock statement on the same monitor:
private readonly object monitor = new object();
private int sharedVariable;
public void MethodThatSetsVariable()
{
    lock (monitor)
    {
        sharedVariable = 5;
    }
}
public void MethodThatReadsVariable()
{
    int foo;
    lock (monitor)
    {
        foo = sharedVariable;
    }
    // Use foo now
}
Alternatives:
- Use a volatilevariable, although the exact behaviour ofvolatileis hard to understand. (Well, it's beyond me, anyway.)
- Use methods on the Interlockedclass
Note that both of these are best suited when it's only a single shared variable you're interested in. When you've got to access a set of variables, making sure you only ever see a fully consistent state, locks are the easiest way to go.
Another option - and preferred if at all possible - is to avoid requiring mutable shared state in the first place. It's not always possible, at least without a complete redesign to a messaging-passing architecture - but it's worth aiming for where possible. Immutable types can help to make this easier to achieve.