ShutDownListener.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ Dotnetfx_Vista_SP2 / Dotnetfx_Vista_SP2 / 8.0.50727.4016 / DEVDIV / depot / DevDiv / releases / Orcas / QFE / wpf / src / Base / MS / Internal / ShutDownListener.cs / 1 / ShutDownListener.cs

                            //---------------------------------------------------------------------------- 
//
// 
//    Copyright (C) Microsoft Corporation.  All rights reserved.
//  
//
// Description: Listen for shut down events on behalf of a target, in a way that 
//          does not leak the target.  ShutDown events include: 
//                  AppDomain.DomainUnload
//                  AppDomain.ProcessExit 
//                  Dispatcher.ShutdownFinished
//          Listening to these events directly can cause leaks, since the AppDomain
//          lives longer than the target.
// 
//          The WeakEvent pattern has similar goals, but can't be used here because
//          the WeakEvent table itself needs to listen for shutdown events. 
// 
//          "Target" refers to the actual consumer of the event(s).  Each class
//          XYZ that wants to consume these events should define a class 
//          XYZShutDownListener deriving from ShutDownListener that overrides the
//          OnShutDown method.  The target's constructor typically creates an
//          instance of the XYZShutDownListener, which holds a weak reference to
//          the target, and listens for the desired events.  When an event occurs, 
//          the OnShutDown override is passed a (normal) reference to the target
//          object, and typically calls an appropriate target method that reacts 
//          to the event.  (See examples in WeakEventTable, DataBindEngine, etc.) 
//---------------------------------------------------------------------------
 
using System;
using System.Security;              // [SecurityCritical]
using System.Windows.Threading;     // Dispatcher
using MS.Internal.WindowsBase;      // [FriendAccessAllowed] 

namespace MS.Internal 
{ 
    [FriendAccessAllowed]   // defined in Base, also used in Framework
    [Flags] 
    internal enum ShutDownEvents : ushort
    {
        DomainUnload        = 0x0001,
        ProcessExit         = 0x0002, 
        DispatcherShutdown  = 0x0004,
 
        AppDomain           = DomainUnload | ProcessExit, 
        All                 = AppDomain | DispatcherShutdown,
    } 

    [FriendAccessAllowed]   // defined in Base, also used in Framework
    internal abstract class ShutDownListener : WeakReference
    { 
        /// 
        /// Critical - accesses AppDomain.DomainUnload event. 
        /// not SecurityTreatAsSafe. 
        /// 
        [SecurityCritical] 
        internal ShutDownListener(object target)
            : this(target, ShutDownEvents.All)
        {
        } 

        ///  
        /// Critical - accesses AppDomain.DomainUnload and AppDomain.ProcessExit events (which have link demands). 
        /// not SecurityTreatAsSafe.
        ///  
        [SecurityCritical]
        internal ShutDownListener(object target, ShutDownEvents events)
            : base(target)
        { 
            _flags = ((PrivateFlags)events) | PrivateFlags.Listening;
 
            if (target == null) 
            {
                _flags |= PrivateFlags.Static; 
            }

            if ((_flags & PrivateFlags.DomainUnload) != 0)
            { 
                AppDomain.CurrentDomain.DomainUnload += new EventHandler(HandleShutDown);
            } 
 
            if ((_flags & PrivateFlags.ProcessExit) != 0)
            { 
                AppDomain.CurrentDomain.ProcessExit += new EventHandler(HandleShutDown);
            }

            if ((_flags & PrivateFlags.DispatcherShutdown) != 0) 
            {
                Dispatcher dispatcher = Dispatcher.CurrentDispatcher; 
                dispatcher.ShutdownFinished += new EventHandler(HandleShutDown); 
                _dispatcherWR = new WeakReference(dispatcher);
            } 
        }

        // derived class should override this method to inform the target that a shutdown
        // event has occurred.  This method might be called on any thread (e.g. 
        // AppDomain.DomainUnload events are typically raised on worker threads).
        abstract internal void OnShutDown(object target); 
 
        // stop listening for shutdown events
        ///  
        ///     Critical: accesses AppDomain.DomainUnload event
        ///     TreatAsSafe: This code does not take any parameter or return state.
        ///                  It simply unattaches private callbacks.
        ///  
        [SecurityCritical,SecurityTreatAsSafe]
        internal void StopListening() 
        { 
            if ((_flags & PrivateFlags.Listening) == 0)
                return; 

            _flags = _flags & ~PrivateFlags.Listening;

            if ((_flags & PrivateFlags.DomainUnload) != 0) 
            {
                AppDomain.CurrentDomain.DomainUnload -= new EventHandler(HandleShutDown); 
            } 

            if ((_flags & PrivateFlags.ProcessExit) != 0) 
            {
                AppDomain.CurrentDomain.ProcessExit -= new EventHandler(HandleShutDown);
            }
 
            if ((_flags & PrivateFlags.DispatcherShutdown) != 0)
            { 
                Dispatcher dispatcher = (Dispatcher)_dispatcherWR.Target; 
                if (dispatcher != null)
                { 
                    dispatcher.ShutdownFinished -= new EventHandler(HandleShutDown);
                }
                _dispatcherWR = null;
            } 
        }
 
        // handle a shutdown event 
        private void HandleShutDown(object sender, EventArgs e)
        { 
            // if the target has been GC'd, no need to listen for events any more
            object target = Target;
            if (target == null && (_flags & PrivateFlags.Static) == 0)
            { 
                StopListening();
                return; 
            } 

            // forward the event to the derived class, which will inform the target 
            OnShutDown(target);
        }

        [Flags] 
        enum PrivateFlags : ushort
        { 
            DomainUnload        = ShutDownEvents.DomainUnload, 
            ProcessExit         = ShutDownEvents.ProcessExit,
            DispatcherShutdown  = ShutDownEvents.DispatcherShutdown, 

            Static              = 0x4000,
            Listening           = 0x8000,
        } 

        PrivateFlags _flags; 
        WeakReference _dispatcherWR; 
    }
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
//---------------------------------------------------------------------------- 
//
// 
//    Copyright (C) Microsoft Corporation.  All rights reserved.
//  
//
// Description: Listen for shut down events on behalf of a target, in a way that 
//          does not leak the target.  ShutDown events include: 
//                  AppDomain.DomainUnload
//                  AppDomain.ProcessExit 
//                  Dispatcher.ShutdownFinished
//          Listening to these events directly can cause leaks, since the AppDomain
//          lives longer than the target.
// 
//          The WeakEvent pattern has similar goals, but can't be used here because
//          the WeakEvent table itself needs to listen for shutdown events. 
// 
//          "Target" refers to the actual consumer of the event(s).  Each class
//          XYZ that wants to consume these events should define a class 
//          XYZShutDownListener deriving from ShutDownListener that overrides the
//          OnShutDown method.  The target's constructor typically creates an
//          instance of the XYZShutDownListener, which holds a weak reference to
//          the target, and listens for the desired events.  When an event occurs, 
//          the OnShutDown override is passed a (normal) reference to the target
//          object, and typically calls an appropriate target method that reacts 
//          to the event.  (See examples in WeakEventTable, DataBindEngine, etc.) 
//---------------------------------------------------------------------------
 
using System;
using System.Security;              // [SecurityCritical]
using System.Windows.Threading;     // Dispatcher
using MS.Internal.WindowsBase;      // [FriendAccessAllowed] 

namespace MS.Internal 
{ 
    [FriendAccessAllowed]   // defined in Base, also used in Framework
    [Flags] 
    internal enum ShutDownEvents : ushort
    {
        DomainUnload        = 0x0001,
        ProcessExit         = 0x0002, 
        DispatcherShutdown  = 0x0004,
 
        AppDomain           = DomainUnload | ProcessExit, 
        All                 = AppDomain | DispatcherShutdown,
    } 

    [FriendAccessAllowed]   // defined in Base, also used in Framework
    internal abstract class ShutDownListener : WeakReference
    { 
        /// 
        /// Critical - accesses AppDomain.DomainUnload event. 
        /// not SecurityTreatAsSafe. 
        /// 
        [SecurityCritical] 
        internal ShutDownListener(object target)
            : this(target, ShutDownEvents.All)
        {
        } 

        ///  
        /// Critical - accesses AppDomain.DomainUnload and AppDomain.ProcessExit events (which have link demands). 
        /// not SecurityTreatAsSafe.
        ///  
        [SecurityCritical]
        internal ShutDownListener(object target, ShutDownEvents events)
            : base(target)
        { 
            _flags = ((PrivateFlags)events) | PrivateFlags.Listening;
 
            if (target == null) 
            {
                _flags |= PrivateFlags.Static; 
            }

            if ((_flags & PrivateFlags.DomainUnload) != 0)
            { 
                AppDomain.CurrentDomain.DomainUnload += new EventHandler(HandleShutDown);
            } 
 
            if ((_flags & PrivateFlags.ProcessExit) != 0)
            { 
                AppDomain.CurrentDomain.ProcessExit += new EventHandler(HandleShutDown);
            }

            if ((_flags & PrivateFlags.DispatcherShutdown) != 0) 
            {
                Dispatcher dispatcher = Dispatcher.CurrentDispatcher; 
                dispatcher.ShutdownFinished += new EventHandler(HandleShutDown); 
                _dispatcherWR = new WeakReference(dispatcher);
            } 
        }

        // derived class should override this method to inform the target that a shutdown
        // event has occurred.  This method might be called on any thread (e.g. 
        // AppDomain.DomainUnload events are typically raised on worker threads).
        abstract internal void OnShutDown(object target); 
 
        // stop listening for shutdown events
        ///  
        ///     Critical: accesses AppDomain.DomainUnload event
        ///     TreatAsSafe: This code does not take any parameter or return state.
        ///                  It simply unattaches private callbacks.
        ///  
        [SecurityCritical,SecurityTreatAsSafe]
        internal void StopListening() 
        { 
            if ((_flags & PrivateFlags.Listening) == 0)
                return; 

            _flags = _flags & ~PrivateFlags.Listening;

            if ((_flags & PrivateFlags.DomainUnload) != 0) 
            {
                AppDomain.CurrentDomain.DomainUnload -= new EventHandler(HandleShutDown); 
            } 

            if ((_flags & PrivateFlags.ProcessExit) != 0) 
            {
                AppDomain.CurrentDomain.ProcessExit -= new EventHandler(HandleShutDown);
            }
 
            if ((_flags & PrivateFlags.DispatcherShutdown) != 0)
            { 
                Dispatcher dispatcher = (Dispatcher)_dispatcherWR.Target; 
                if (dispatcher != null)
                { 
                    dispatcher.ShutdownFinished -= new EventHandler(HandleShutDown);
                }
                _dispatcherWR = null;
            } 
        }
 
        // handle a shutdown event 
        private void HandleShutDown(object sender, EventArgs e)
        { 
            // if the target has been GC'd, no need to listen for events any more
            object target = Target;
            if (target == null && (_flags & PrivateFlags.Static) == 0)
            { 
                StopListening();
                return; 
            } 

            // forward the event to the derived class, which will inform the target 
            OnShutDown(target);
        }

        [Flags] 
        enum PrivateFlags : ushort
        { 
            DomainUnload        = ShutDownEvents.DomainUnload, 
            ProcessExit         = ShutDownEvents.ProcessExit,
            DispatcherShutdown  = ShutDownEvents.DispatcherShutdown, 

            Static              = 0x4000,
            Listening           = 0x8000,
        } 

        PrivateFlags _flags; 
        WeakReference _dispatcherWR; 
    }
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK