I want to use Thread.VolatileWrite() (or an equivalent function) to change the value of a T[] field, so that the updated value is immediately visible to all other threads. However, the method does not provide a generic version, and I'm not able to use the Object overload since it takes a ref parameter.
Is there an alternative? Would Interlocked.Exchange<T> do the job? Is there a better way to achieve what I want to do?
-
You can maybe use the volatile modifier. But check the documentation to see that the limitation don't apply to your case. And there is probably a performance penalty for using it.
Update: About using Interlocked. Notice that the documentation doesn't state that the changed value is visible to all threads. So it is probably not the same. But if you are in a situation that this is important. You must investigate further all the concurrency disaster possibilities.
Hosam Aly : Thank you. I am already using the volatile modifier, and I was hoping I could avoid its penalty by calling VolatileWrite explicitly. (Please see my comment on Marc's answer.) Thanks. -
VolatileWriteis only useful if you also useVolatileRead; thevolatilemodifier is easier to use, but I wonder if it wouldn't be simpler to use synchronization - perhaps aReaderWriterLockSlim(since it sounds like you have lots of readers).Interlocked.Exchange<T>simply performs the get and set as an atomic operation; it doesn't (AFAIK) make any volatility claims (indeed, the compiler even tells you that avolatilefield won't be treated asvolatilewhen used as arefargument).
Edit to clarify "it doesn't (AFAIK) make any volatility claims" - the behaviour of
Interlockedis predictable, and you should see updates immediately on other thread as long as they also useInterlocked; my point is that if one thread usesInterlocked, and another relies onvolatile(to talk to the same field), I don't know of any guarantees. Stick to one or the other for all access.Hosam Aly : So you mean that, unless I use `VolatileRead` too, other threads may still have a cached value of the field?Marc Gravell : Exactly. Hence the `volatile` modifier to make this simpler.Hosam Aly : I was trying to use it in favor of using a volatile field, since that field is accessed very frequently, but only written to very, very few times (e.g. accessed 3n times, while written log(n) times only). So I thought I could introduce VolatileWrite only in write cases...Jon Skeet : @Hosam: The problem is that unless the reading threads know to make sure they don't get a cached version, they could just not both looking at the newly published version. In fact, I believe that .NET (i.e. the MS CLI implementation) makes all writes volatile anyway - it's reads that need extra care.Hosam Aly : Thank you Mark and Jon for your informative replies. :)
0 comments:
Post a Comment