Do Volatile.Read
and Volatile.Write
have the exact same effect on a nonvolatile int that normal reads and assignments have on an int with the volatile
modifier?
The motivation is to prevent the warning that volatile
variables should not be passed via ref parameters to the Interlocked
methods. (I understand that the program is correct in spite of the warning, but I'd rather not leave enigmatic pragmas in my code.)
//private volatile int suppressListChangedEvents;
private int suppressListChangedEvents;
public void SuppressListChangedEvents()
{
Interlocked.Increment(ref suppressListChangedEvents);
}
public void UnsuppressListChangedEvents()
{
if (Interlocked.Decrement(ref suppressListChangedEvents) < 0)
throw new InvalidOperationException("Too many calls to unsuppress.");
}
protected override void OnListChanged(ListChangedEventArgs e)
{
//if (suppressListChangedEvents != 0) return;
if (Volatile.Read(ref suppressListChangedEvents) != 0) return;
base.OnListChanged(e);
}
Likewise, I have a DirectX render thread pump that consumes commands using Interlocked.Exchange(ref command, null)
and some commands are produced using direct assignment to the volatile command
variable. Can I safely change that to Volatile.Write
and remove the volatile
modifier without introducing overhead?
EDIT: Definitive answer. Going forward, I'll shun the modifier and always explicitly access the variable via Volatile and Interlocked. That way the code has no ambiguity about the type of access; altering the variable declaration will not change the meaning of the code.
In a perfect world, I would make the volatile
modifier useful by having the compiler deny the ability to directly reference or assign to the variable. That would force me to pass the reference to Volatile or Interlocked or a method that would itself use Volatile or Interlocked. I should get my hands on a copy of Roslyn.
There is no difference in your scenario; the only difference exists when talking about individual array elements:
In C#, using the
volatile
modifier on a field guarantees that every access to that field uses theVolatile.Read
andVolatile.Write
methods, but thevolatile
modifier cannot be applied to array elements. TheVolatile.Read
andVolatile.Write
methods can be used on array elements.
So, as long as you are absolutely sure that you have caught all usages of the fields in question, you can safely change the blanket volatile
to explicit volatile reads/writes.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With