What does the exit context mean for a WaitHandle.WaitOne mean?
Asked Answered
S

2

15

I'm trying to use a mutex to protect access to some hardware from multiple threads, but I'm confused as to what the exitContext parameter means / does:

public virtual bool WaitOne (
    int millisecondsTimeout,
    bool exitContext
)

The docs say:

exitContext - true to exit the synchronization domain for the context before the wait (if in a synchronized context), and reacquire it afterward; otherwise, false.

...but what does that actually mean and what are the consequences of setting it to either true or false? I've set it to true for now and the code appears to work, but I'm nervous that I don't fully understand what it's up to under the hood!

Smelt answered 19/10, 2011 at 16:15 Comment(0)
F
5

It also explains further down the page under Remarks that:

Notes on Exiting the Context

The exitContext parameter has no effect unless the WaitOne method is called from inside a nondefault managed context. This can happen if your thread is inside a call to an instance of a class derived from ContextBoundObject. Even if you are currently executing a method on a class that does not derive from ContextBoundObject, like String, you can be in a nondefault context if a ContextBoundObject is on your stack in the current application domain.

When your code is executing in a nondefault context, specifying true for exitContext causes the thread to exit the nondefault managed context (that is, to transition to the default context) before executing the WaitOne method. The thread returns to the original nondefault context after the call to the WaitOne method completes.

This can be useful when the context-bound class has SynchronizationAttribute. In that case, all calls to members of the class are automatically synchronized, and the synchronization domain is the entire body of code for the class. If code in the call stack of a member calls the WaitOne method and specifies true for exitContext, the thread exits the synchronization domain, allowing a thread that is blocked on a call to any member of the object to proceed. When the WaitOne method returns, the thread that made the call must wait to reenter the synchronization domain.

Firing answered 19/10, 2011 at 16:18 Comment(0)
R
17

The Remark section of MSDN page reads like utter gobbledegook of course. Execution contexts are a well-hidden implementation detail in .NET. I'll just tell you what I reversed engineered without being able to completely nail it down.

The exitContext argument is relevant in remoting scenarios only. By passing true, you allow the current call to be suspended and another call to be marshaled from the client to the server. You'd do so to improve throughput, selecting true only when you expect the WaitOne() call to take a while. The exact implications of doing so are however not obvious to me, nor documented anywhere I know of. The WaitOne() overload (no timeout) always passes false, that puts some strain on my explanation unfortunately.

A side-story behind this method is that it is so poorly understood that Microsoft decided to break backward compatibility in .NET 2. They added the WaitOne(int) overload in service pack 2. Which passes false for the exitContext argument. This caused a lot of mayhem, programmers started using it then found their program to fail when run on a pre-SP2 version of .NET. Ouch.

Rhodie answered 19/10, 2011 at 16:15 Comment(0)
F
5

It also explains further down the page under Remarks that:

Notes on Exiting the Context

The exitContext parameter has no effect unless the WaitOne method is called from inside a nondefault managed context. This can happen if your thread is inside a call to an instance of a class derived from ContextBoundObject. Even if you are currently executing a method on a class that does not derive from ContextBoundObject, like String, you can be in a nondefault context if a ContextBoundObject is on your stack in the current application domain.

When your code is executing in a nondefault context, specifying true for exitContext causes the thread to exit the nondefault managed context (that is, to transition to the default context) before executing the WaitOne method. The thread returns to the original nondefault context after the call to the WaitOne method completes.

This can be useful when the context-bound class has SynchronizationAttribute. In that case, all calls to members of the class are automatically synchronized, and the synchronization domain is the entire body of code for the class. If code in the call stack of a member calls the WaitOne method and specifies true for exitContext, the thread exits the synchronization domain, allowing a thread that is blocked on a call to any member of the object to proceed. When the WaitOne method returns, the thread that made the call must wait to reenter the synchronization domain.

Firing answered 19/10, 2011 at 16:18 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.