File: Base\System\Windows\Threading\DispatcherFrame.cs
Project: wpf\src\WindowsBase.csproj (WindowsBase)
using System;
using System.Security; 
 
namespace System.Windows.Threading
{
    /// <summary>
    ///     Representation of Dispatcher frame.
    /// </summary>
    public class DispatcherFrame : DispatcherObject
    {
 
        /// <SecurityNote>
        ///     Critical: This code exists to ensure that the static variables initialized
        ///     do not cause security violations.The reason this comes into existance is because
        ///     of the call to RegisterWindowMessage
        ///     TreatAsSafe:This is safe to call
        /// </SecurityNote>
        [SecurityCritical,SecurityTreatAsSafe]
        static DispatcherFrame()
        {
        }
 
        /// <summary>
        ///     Constructs a new instance of the DispatcherFrame class.
        /// </summary>
        public DispatcherFrame() : this(true)
        {
        }
        
        /// <summary>
        ///     Constructs a new instance of the DispatcherFrame class.
        /// </summary>
        /// <param name="exitWhenRequested">
        ///     Indicates whether or not this frame will exit when all frames
        ///     are requested to exit.
        ///     <p/>
        ///     Dispatcher frames typically break down into two categories:
        ///     1) Long running, general purpose frames, that exit only when
        ///        told to.  These frames should exit when requested.
        ///     2) Short running, very specific frames that exit themselves
        ///        when an important criteria is met.  These frames may
        ///        consider not exiting when requested in favor of waiting
        ///        for their important criteria to be met.  These frames
        ///        should have a timeout associated with them.
        /// </param>
        public DispatcherFrame(bool exitWhenRequested)
        {
            _exitWhenRequested = exitWhenRequested;
            _continue = true;
        }
 
        /// <summary>
        ///     Indicates that this dispatcher frame should exit.
        /// </summary>
        /// <SecurityNote>
        ///     Critical - calls a critical method - postThreadMessage. 
        ///     PublicOK - all we're doing is posting a current message to our thread. 
        ///                net effect is the dispatcher "wakes up"
        ///                and uses the continue flag ( which may have just changed). 
        /// </SecurityNote> 
        public bool Continue
        {
            get
            {
                // This method is free-threaded.
                    
                // First check if this frame wants to continue.
                bool shouldContinue = _continue;
                if(shouldContinue)
                {
                    // This frame wants to continue, so next check if it will
                    // respect the "exit requests" from the dispatcher.
                    if(_exitWhenRequested)
                    {
                        Dispatcher dispatcher = Dispatcher;
                        
                        // This frame is willing to respect the "exit requests" of
                        // the dispatcher, so check them.
                        if(dispatcher._exitAllFrames || dispatcher._hasShutdownStarted)
                        {
                            shouldContinue = false;
                        }
                    }
                }
                
                return shouldContinue;
            }
 
            [SecurityCritical] 
            set
            {
                // This method is free-threaded.
 
                _continue = value;
 
                // Post a message so that the message pump will wake up and
                // check our continue state.
                Dispatcher.BeginInvoke(DispatcherPriority.Send, (DispatcherOperationCallback) delegate(object unused) {return null;}, null);
            }
        }
 
        private bool _exitWhenRequested;
        private bool _continue;
    }
}