I have a variable which I am using to represent state. It can be read and written to from multiple threads.
I am using Interlocked.Exchange
and In
Interlocked operations and volatile are not really supposed to be used at the same time. The reason you get a warning is because it (almost?) always indicates you have misunderstood what you are doing.
Over-simplifying and paraphrasing:
volatile
indicates that every read operation needs to re-read from memory because there might be other threads updating the variable. When applied to a field that can be read/written atomically by the architecture you are running on, this should be all you need to do unless you are using long/ulong, most other types can be read/written atomically.
When a field is not marked volatile, you can use Interlocked
operations to make a similar guarantee, because it causes the cache to be flushed so that the update will be visible to all other processors... this has the benefit that you put the overhead on the update rather than the read.
Which of these two approaches performs best depends on what exactly you are doing. And this explanation is a gross over-simplification. But it should be clear from this that doing both at the same time is pointless.
You can safely disregard that warning when you're using Interlocked.Xxx
functions (see this question), because they always do volatile operations. So a volatile
variable is perfectly OK for shared state. If you want to get rid of the warning at all costs, you actually can do an interlocked read with Interlocked.CompareExchange (ref counter, 0, 0)
.
Edit: Actually, you need volatile
on your state variable only if you are going to write to it directly (i.e. not using Interlocked.Xxx
). As jerryjvl mentioned, reads of a variable updated with an interlocked (or volatile) operation will use the most recent value.