private void CallWithNonPumpingWait(Action callback)
        {
            SynchronizationContext           oldSynchronizationContext        = SynchronizationContext.Current;
            NonPumpingSynchronizationContext nonPumpingSynchronizationContext =
                Interlocked.Exchange <NonPumpingSynchronizationContext>(ref _defaultSynchronizationContext, null);

            // if the default non-pumping context is in use, allocate a new one
            bool usingDefaultContext = (nonPumpingSynchronizationContext != null);

            if (!usingDefaultContext)
            {
                nonPumpingSynchronizationContext = new NonPumpingSynchronizationContext();
            }

            try
            {
                // install the non-pumping context
                nonPumpingSynchronizationContext.Parent = oldSynchronizationContext;
                SynchronizationContext.SetSynchronizationContext(nonPumpingSynchronizationContext);

                // invoke the callback
                callback();
            }
            finally
            {
                // restore the old context
                SynchronizationContext.SetSynchronizationContext(oldSynchronizationContext);

                // put the default non-pumping context back into play
                if (usingDefaultContext)
                {
                    Interlocked.Exchange <NonPumpingSynchronizationContext>(ref _defaultSynchronizationContext, nonPumpingSynchronizationContext);
                }
            }
        }
        //------------------------------------------------------
        //
        //  Constructors
        //
        //------------------------------------------------------

        #region Constructors

        internal ReaderWriterLockWrapper()
        {
            // ideally we'd like to use the NoRecursion policy, but RWLock supports
            // recursion so we allow recursion for compat.  It's needed for at least
            // one pattern - a weak event manager for an event A that delegates to
            // a second event B via a second weak event manager.  There's at least
            // one instance of this within WPF (CanExecuteChanged delegates to
            // RequerySuggested), and it could also happen in user code.
            _rwLock = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);
            _defaultSynchronizationContext = new NonPumpingSynchronizationContext();
            Initialize(!MS.Internal.BaseAppContextSwitches.EnableWeakEventMemoryImprovements);
        }