You need to distinguish between "atomic" and "thread-safe" more closely. As you say, writes are atomic for most built-in value types and references.
However, that doesn't mean they're thread-safe. It just means that if values "A" and "B" are both written, a thread will never see something in between. (e.g. a change from 1 to 4 will never show 5, or 2, or any value other than 1 or 4.) It doesn't mean that one thread will see value "B" as soon as it's been written to the variable. For that, you need to look at the memory model in terms of volatility. Without memory barriers, usually obtained through locking and/or volatile variables, writes to main memory may be delayed and reads may be advanced, effectively assuming that the value hasn't changed since the last read.
If you had a counter and you asked it for its latest value but never received the latest value because of a lack of memory barriers, I don't think you could reasonably call that thread-safe even though each operation may well be atomic.
This has nothing to do with properties, however - properties are simply methods with syntactic sugar around them. They make no extra guarantees around threading. The .NET 2.0 memory model does have more guarantees than the ECMA model, and it's possible that it makes guarantees around method entry and exit. Those guarantees should apply to properties as well, although I'd be nervous around the interpretation of such rules: it can be very difficult to reason about memory models sometimes.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…