locked
Unstoppable race condition in windows.forms RRS feed

  • Question

  • I have encountered an interesting race condition and can't seem to avoid it.

    Let's say you have a thread [B] which is about to do Invoke for some UI update. Now suppose that the UI thread [A] has just gotten the closing event and is beginning to process it.

    My understanding is that the invoke causes thread [B] to be handled on thread [A]. If so, and if the handler for closing involves waiting for thread [B] to complete its work, then there is a deadlock which can only be resolved by having thread [A] abort thread [B].

    Is this true? I realize that I could possibly get around this by using BeginInvoke instead, but what if that isn't an option? Setting some lock or bool as the first operation in the handler is still no good, since all that will do is reduce the likelihood... not eliminate it.

    Thoughts?

    Wednesday, March 23, 2011 9:31 PM

Answers

  • You can synchronize this.  It is guaranteed, 100%.  Declare a semaphore somewhere globally accessible that controls Thread A closing code.  In other words, thread A can only close things if it acquires the semaphore (or critical section, meaning an object using Lock() in .Net).  If it cannot acquire the lock, then just abort the closing attempt.  This should allow the Invoke() from thread B.

    In thread B you acquire the semaphore or critical section, while in thread A you only try to.  Oh, and I think a manual reset event is also needed for waiting for thread B in order to signal "too late thread B, I already closed stuff so don't Invoke()".  This should be sufficient for full, 100% fool proof synchronization.


    MCP
    • Proposed as answer by eryang Tuesday, March 29, 2011 9:22 AM
    • Marked as answer by eryang Monday, April 11, 2011 3:05 AM
    Thursday, March 24, 2011 12:17 AM

All replies

  • Yeh!  You should cancel closing thread[A],  stop thread[B], wait for thread[B] to stop and close thread[A].  The pattern occurs with the SerialPort using the DataReceived event.
    Wednesday, March 23, 2011 10:44 PM
  • You can synchronize this.  It is guaranteed, 100%.  Declare a semaphore somewhere globally accessible that controls Thread A closing code.  In other words, thread A can only close things if it acquires the semaphore (or critical section, meaning an object using Lock() in .Net).  If it cannot acquire the lock, then just abort the closing attempt.  This should allow the Invoke() from thread B.

    In thread B you acquire the semaphore or critical section, while in thread A you only try to.  Oh, and I think a manual reset event is also needed for waiting for thread B in order to signal "too late thread B, I already closed stuff so don't Invoke()".  This should be sufficient for full, 100% fool proof synchronization.


    MCP
    • Proposed as answer by eryang Tuesday, March 29, 2011 9:22 AM
    • Marked as answer by eryang Monday, April 11, 2011 3:05 AM
    Thursday, March 24, 2011 12:17 AM
  • We temporarily mark a reply since the thread idle for a long time, please remember to click "Mark as Answer" on the post that helps you, and to click "Unmark as Answer" if a marked post does not actually answer your question. This can be beneficial to other community members reading the thread.
    Eric Yang [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Monday, April 11, 2011 3:05 AM