none
Multithreaded objects and collections RRS feed

  • Question

  • Hello,
     
    I've got a class that uses an object that fires an event. The event comes back on a different thread.

    In my main class I have a collection of objects that are created on the main thread.

    When the event comes in on the different thread, I access the collection that was created on the main thread and get an object and set a value.

    Problem is that "sometimes" the value for the object isn't recognized by the main thread, but sometimes it is.

    I've read a ton of articles on threading, synchronization, caching the volatile keyword etc, but haven't found what I need. I still don't completely understand volatile and how that caching stuff works, but I'm pretty sure this is where my problem is.

    I was thinkinking that I could check to see if InvokeRequired, and invoke the call from the second thread into the primary thread, but I don't think I should have to do this, and kind of don't want to because of the overhead.


    Does anyone have any suggestions? Is this the right place to ask?

    Thanks Ken

    Monday, August 11, 2008 9:43 PM

Answers

  • Quote> Am I correct in that all the lock keyword does is keep...

    I smell a problem.  You'll need the lock keyword around *all* the code that touches a variable that is accessed by multiple threads.  If you didn't make the variable private through a property or method, you need more than one lock statement.

    Forget about "register caching" or the volatile keyword or looking at IL, that doesn't work on multi-core CPUs that each have their own cache.  You need "lock" to ensure that all cores have a unified view of memory.

    Hans Passant.
    • Marked as answer by Zhi-Xin Ye Friday, August 15, 2008 11:23 AM
    Tuesday, August 12, 2008 11:06 PM
    Moderator

All replies

  • You'll only need to use InvokeRequired and (Begin)Invoke() if the object you manipulate is derived from the Control class or is data bound to a control.  For any other object, you must use the lock keyword both in your event handler and the other code that manipulates the object.
    Hans Passant.
    Tuesday, August 12, 2008 3:25 AM
    Moderator
  • Hey Hans,

    I've got the lock keyword on my object when I do the update. Am I correct in that all the lock keyword does is keep multiple threads from updating the object at the same time right? I could either use lock{} or use a ReaderWriterLock for my thread synchronization to mark my critical sections right? From what I've read the lock keyword does not prevent optimizations that would prevent register caching, which is where I think my problem is.

    I've done some more reading and learned enough to now be pretty sure that my problem is with register caching.

    Getting around the problem is another story though. I've learned that the volatile keyword will force a direct memory lookup of an object every time, however what happens to the objects inside a collection when the collection being used is declared with the volatile keyword?

    I'm going to try to build a sample and look at the IL so I can be certain, but if you or anyone knows more about this it would be a great help.
    Tuesday, August 12, 2008 6:38 PM
  • Quote> Am I correct in that all the lock keyword does is keep...

    I smell a problem.  You'll need the lock keyword around *all* the code that touches a variable that is accessed by multiple threads.  If you didn't make the variable private through a property or method, you need more than one lock statement.

    Forget about "register caching" or the volatile keyword or looking at IL, that doesn't work on multi-core CPUs that each have their own cache.  You need "lock" to ensure that all cores have a unified view of memory.

    Hans Passant.
    • Marked as answer by Zhi-Xin Ye Friday, August 15, 2008 11:23 AM
    Tuesday, August 12, 2008 11:06 PM
    Moderator