Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / wpf / src / Base / MS / Internal / ShutDownListener.cs / 1305600 / 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.)
//
// Shutdown is a "one-time" process. When the ShutDownListener receives
// any one of the desired events, it stops listening to all events.
//---------------------------------------------------------------------------
using System;
using System.Security; // [SecurityCritical]
using System.Threading; // Interlocked
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, object sender, EventArgs e);
// 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)
{
// The dispatcher and AppDomain events might arrive on separate threads
// at the same time. The interlock assures that we only do the work
// once.
if (Interlocked.Exchange(ref _inShutDown, 1) == 0)
{
// ShutDown is a one-time event. Stop listening (thus releasing
// references to the ShutDownListener).
StopListening();
// do the shutdown work, unless the target has been GC'd already.
object target = Target;
if (target != null || (_flags & PrivateFlags.Static) != 0)
{
OnShutDown(target, sender, e);
}
}
}
[Flags]
enum PrivateFlags : ushort
{
DomainUnload = ShutDownEvents.DomainUnload,
ProcessExit = ShutDownEvents.ProcessExit,
DispatcherShutdown = ShutDownEvents.DispatcherShutdown,
Static = 0x4000,
Listening = 0x8000,
}
PrivateFlags _flags;
WeakReference _dispatcherWR;
int _inShutDown;
}
}
// 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.)
//
// Shutdown is a "one-time" process. When the ShutDownListener receives
// any one of the desired events, it stops listening to all events.
//---------------------------------------------------------------------------
using System;
using System.Security; // [SecurityCritical]
using System.Threading; // Interlocked
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, object sender, EventArgs e);
// 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)
{
// The dispatcher and AppDomain events might arrive on separate threads
// at the same time. The interlock assures that we only do the work
// once.
if (Interlocked.Exchange(ref _inShutDown, 1) == 0)
{
// ShutDown is a one-time event. Stop listening (thus releasing
// references to the ShutDownListener).
StopListening();
// do the shutdown work, unless the target has been GC'd already.
object target = Target;
if (target != null || (_flags & PrivateFlags.Static) != 0)
{
OnShutDown(target, sender, e);
}
}
}
[Flags]
enum PrivateFlags : ushort
{
DomainUnload = ShutDownEvents.DomainUnload,
ProcessExit = ShutDownEvents.ProcessExit,
DispatcherShutdown = ShutDownEvents.DispatcherShutdown,
Static = 0x4000,
Listening = 0x8000,
}
PrivateFlags _flags;
WeakReference _dispatcherWR;
int _inShutDown;
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- XmlILOptimizerVisitor.cs
- ResolveDuplex11AsyncResult.cs
- XmlnsPrefixAttribute.cs
- DockEditor.cs
- EventLogPermissionAttribute.cs
- UnknownBitmapEncoder.cs
- CommunicationException.cs
- ControlPaint.cs
- OleDbRowUpdatedEvent.cs
- sqlpipe.cs
- ApplicationInfo.cs
- UidPropertyAttribute.cs
- GetWinFXPath.cs
- SlipBehavior.cs
- TypeInfo.cs
- CompositeDataBoundControl.cs
- ZipFileInfo.cs
- Size.cs
- ConvertTextFrag.cs
- TextEndOfLine.cs
- OdbcParameter.cs
- OracleTimeSpan.cs
- ColorKeyFrameCollection.cs
- NodeFunctions.cs
- DataViewListener.cs
- ButtonChrome.cs
- EditingMode.cs
- OdbcHandle.cs
- EditorPart.cs
- NetStream.cs
- NativeMethods.cs
- AutomationPropertyInfo.cs
- FormViewCommandEventArgs.cs
- DataKeyArray.cs
- TextContainerChangedEventArgs.cs
- CompositeControl.cs
- MemberRelationshipService.cs
- BufferModesCollection.cs
- RankException.cs
- ProgressBar.cs
- ItemsPresenter.cs
- SmtpAuthenticationManager.cs
- ToolConsole.cs
- Bezier.cs
- XPathNodeHelper.cs
- Models.cs
- PlatformCulture.cs
- FileSecurity.cs
- EntityDataSourceDesigner.cs
- ContextStack.cs
- path.cs
- ByteFacetDescriptionElement.cs
- StateChangeEvent.cs
- MouseOverProperty.cs
- MenuItem.cs
- NamespaceInfo.cs
- Properties.cs
- DataContractSerializerSection.cs
- PassportPrincipal.cs
- ProgressBarAutomationPeer.cs
- NativeMethodsCLR.cs
- PersonalizableTypeEntry.cs
- CommonGetThemePartSize.cs
- HtmlDocument.cs
- TransformerInfo.cs
- StaticContext.cs
- DuplexSecurityProtocolFactory.cs
- DataGridColumnHeaderCollection.cs
- StrokeNodeOperations.cs
- EdmItemCollection.cs
- PasswordTextNavigator.cs
- WrappedOptions.cs
- MultiPartWriter.cs
- EmptyEnumerable.cs
- BooleanProjectedSlot.cs
- DataKeyCollection.cs
- Geometry3D.cs
- GeneratedView.cs
- ImageSource.cs
- CrossSiteScriptingValidation.cs
- SQLDouble.cs
- ProcessHostServerConfig.cs
- MatrixUtil.cs
- UnmanagedMemoryStream.cs
- ObjectDataSourceMethodEventArgs.cs
- UIElement3D.cs
- CapabilitiesUse.cs
- BasicKeyConstraint.cs
- CompilerError.cs
- TraversalRequest.cs
- HeaderCollection.cs
- DictionaryTraceRecord.cs
- Preprocessor.cs
- QueryStringParameter.cs
- BlurBitmapEffect.cs
- SystemSounds.cs
- StreamInfo.cs
- ChangeInterceptorAttribute.cs
- ExpressionSelection.cs
- SecurityTokenException.cs