Code:
/ Dotnetfx_Vista_SP2 / Dotnetfx_Vista_SP2 / 8.0.50727.4016 / DEVDIV / depot / DevDiv / releases / Orcas / QFE / wpf / src / Core / CSharp / System / Windows / Input / Stylus / DynamicRendererThreadManager.cs / 1 / DynamicRendererThreadManager.cs
//----------------------------------------------------------------------------
//
// File: DynamicRendererThreadManager.cs
//
// Description:
// Dynamic Renderering Dispatcher - Provides shared Dispatcher for off application
// Dispatcher inking support.
//
// Copyright (C) 2003-2004 by Microsoft Corporation. All rights reserved.
//
//---------------------------------------------------------------------------
using System;
using System.Diagnostics;
using System.Collections.Specialized;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Input;
using System.Windows.Media;
using System.Threading;
using System.Windows.Threading;
using MS.Utility;
using System.Security;
using System.Security.Permissions;
using MS.Internal;
namespace System.Windows.Input.StylusPlugIns
{
///
/// Manager for the Dispatcher.ShutdownStarted event.
///
// Note: this class should have the same visibility (public / internal /
// private) as the event it manages. If the event is not public, change
// the visibility of this class accordingly.
internal sealed class DispatcherShutdownStartedEventManager : WeakEventManager
{
#region Constructors
//
// Constructors
//
private DispatcherShutdownStartedEventManager()
{
}
#endregion Constructors
#region Public Methods
//
// Public Methods
//
///
/// Add a listener to the given source's event.
///
///
/// Critical: Called only by SecurityCritical code DynamicRendererThreadManager::ctor
///
[SecurityCritical]
public static void AddListener(Dispatcher source, IWeakEventListener listener)
{
CurrentManager.ProtectedAddListener(source, listener);
}
#endregion Public Methods
#region Protected Methods
//
// Protected Methods
//
///
/// Listen to the given source for the event.
///
protected override void StartListening(object source)
{
Dispatcher typedSource = (Dispatcher)source;
typedSource.ShutdownStarted += new EventHandler(OnShutdownStarted);
}
///
/// Stop listening to the given source for the event.
///
protected override void StopListening(object source)
{
Dispatcher typedSource = (Dispatcher)source;
typedSource.ShutdownStarted -= new EventHandler(OnShutdownStarted);
}
#endregion Protected Methods
#region Private Properties
//
// Private Properties
//
///
/// get the event manager for the current thread
///
///
/// Critical: Called only by SecurityCritical code DynamicRendererThreadManager::ctor
///
private static DispatcherShutdownStartedEventManager CurrentManager
{
[SecurityCritical]
get
{
Type managerType = typeof(DispatcherShutdownStartedEventManager);
DispatcherShutdownStartedEventManager manager = (DispatcherShutdownStartedEventManager)GetCurrentManager(managerType);
// at first use, create and register a new manager
if (manager == null)
{
manager = new DispatcherShutdownStartedEventManager();
SetCurrentManager(managerType, manager);
}
return manager;
}
}
#endregion Private Properties
#region Private Methods
//
// Private Methods
//
// event handler for ShutdownStarted event
private void OnShutdownStarted(object sender, EventArgs args)
{
DeliverEvent(sender, args);
}
#endregion Private Methods
}
/////////////////////////////////////////////////////////////////////////
///
/// This class provides a Dispatcher on a shared thread for use in real time inking. Each
/// instance of this class must call Dispose() in order to have this thread shut
/// down properly.
///
internal class DynamicRendererThreadManager : IWeakEventListener, IDisposable
{
[ThreadStatic]
private static WeakReference _tsDRTMWeakRef;
internal static DynamicRendererThreadManager GetCurrentThreadInstance()
{
// Create the threadstatic DynamicRendererThreadManager as needed for calling thread.
// It only creates one
if (_tsDRTMWeakRef == null || _tsDRTMWeakRef.Target == null)
{
_tsDRTMWeakRef = new WeakReference(new DynamicRendererThreadManager());
}
return _tsDRTMWeakRef.Target as DynamicRendererThreadManager;
}
private volatile Dispatcher __inkingDispatcher; // Can be accessed from multiple threads.
private bool _disposed;
///
/// Private contructor called by static method so that we can only ever create one of these per thread!
///
///
/// Critical: This code creates a singleton thread that runs it own Dispatcher pump via InkingThreadProc.
/// Called by DynamicRenderer.CreateRealTimeVisuals().
/// TreatAsSafe: Calling this over and over can only create one shared thread with its own dispatcher which is at
/// the most a nuisance.
///
[SecurityCritical,SecurityTreatAsSafe]
private DynamicRendererThreadManager()
{
// Create the thread
DynamicRendererThreadManagerWorker worker = new DynamicRendererThreadManagerWorker();
__inkingDispatcher = worker.StartUpAndReturnDispatcher();
// NTRAID:WINDOWSOS#1877251-2006/10/10-WAYNEZEN,
// Add a weak listener to the application dispatcher's ShutdownStarted event. So we can
// shut down our dynamic rendering thread gracefully when the app dispatcher is being shut down.
DispatcherShutdownStartedEventManager.AddListener(Dispatcher.CurrentDispatcher, this);
Debug.Assert(__inkingDispatcher != null); // We should have a valid ref here
}
// Finalizer - clean up thread
~DynamicRendererThreadManager()
{
Dispose(false);
}
///
/// IDisposable.Dispose implementation.
///
public void Dispose()
{
// NOTE: This object is internal to the DynamicRenderer and you really shouldn't call this.
// It's was added to be consistent with .NET design guidelines.
// Just let the finalizer do any required clean up work!
Dispose(true);
GC.SuppressFinalize(this);
}
///
/// Handle events from the centralized event table
///
bool IWeakEventListener.ReceiveWeakEvent(Type managerType, object sender, EventArgs args)
{
//NOTE: if DispatcherShutdownStartedEventManager is updated to listen
//to anything besides ShutdownStarted, you should disambiguate the event here
if (managerType == typeof(DispatcherShutdownStartedEventManager))
{
OnAppDispatcherShutdown(sender, args);
}
else
{
return false; // unrecognized event
}
return true;
}
///
/// The app dispatcher Shutdown Handler
///
///
///
private void OnAppDispatcherShutdown(object sender, EventArgs e)
{
Dispatcher inkingDispatcher = __inkingDispatcher;
// Return from here if the inking dispathcer is gone already.
if (inkingDispatcher == null)
return;
// Mashal the Dispose call, which will shut down our Dynamic rendering thread, to the inking dispatcher.
inkingDispatcher.Invoke(DispatcherPriority.Send,
(DispatcherOperationCallback)delegate(object unused)
{
Dispose();
return null;
},
null);
}
///
/// Handles disposing of internal object data.
///
/// true when freeing managed and unmanaged resources; false if freeing just unmanaged resources.
///
/// Critical - Calls SecurityCritical method Dispatcher.CriticalShutdown.
/// Called by Dispose() and Finalizer.
/// TreatAsSafe - No critical data returned or accepted as input.
///
[SecurityCritical, SecurityTreatAsSafe]
void Dispose(bool disposing)
{
if(!_disposed)
{
_disposed = true;
// Free up the thread
if (__inkingDispatcher != null && !Environment.HasShutdownStarted)
{
try
{
__inkingDispatcher.CriticalInvokeShutdown();
}
catch(System.ComponentModel.Win32Exception e)
{
if (e.NativeErrorCode != 1400) // ERROR_INVALID_WINDOW_HANDLE
{
// This is an unlocalized string but it only prints on the Debug Console
Debug.WriteLine(String.Format("Dispatcher.CriticalInvokeShutdown() Failed. Error={0}", e.NativeErrorCode));
}
}
finally
{
__inkingDispatcher = null;
}
}
}
GC.KeepAlive(this);
}
///
/// Gets the inking thread dispatcher.
///
internal Dispatcher ThreadDispatcher
{
get
{
return __inkingDispatcher;
}
}
// Helper class to manager the thread startup and thread proc. Needed in order to allow
// the DynamicRendererThreadManager to get garbage collected.
private class DynamicRendererThreadManagerWorker
{
private Dispatcher _dispatcher;
private AutoResetEvent _startupCompleted;
///
/// Constructor.
///
internal DynamicRendererThreadManagerWorker()
{
}
///
/// Critical: This code creates a singleton thread that runs it own Dispatcher pump via InkingThreadProc.
/// Called by DynamicRendererThreadManager constructor.
/// the most a nuisance.
///
[SecurityCritical]
internal Dispatcher StartUpAndReturnDispatcher()
{
_startupCompleted = new AutoResetEvent(false);
Thread inkingThread = new Thread(new ThreadStart(InkingThreadProc));
inkingThread.SetApartmentState(ApartmentState.STA);
inkingThread.IsBackground = true; // Don't keep process alive if this thread still running.
inkingThread.Start();
_startupCompleted.WaitOne();
_startupCompleted.Close();
_startupCompleted = null;
return _dispatcher;
}
///
/// Critical: This code calls into Dispatcher.Run on a given thread
///
[SecurityCritical]
public void InkingThreadProc()
{
Thread.CurrentThread.Name = "DynamicRenderer";
// Now make sure we create the dispatcher.
_dispatcher = Dispatcher.CurrentDispatcher;
// Now we can signal that everything is set up.
_startupCompleted.Set();
// Now start the dispatcher message loop for this thread.
Dispatcher.Run();
}
}
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
//----------------------------------------------------------------------------
//
// File: DynamicRendererThreadManager.cs
//
// Description:
// Dynamic Renderering Dispatcher - Provides shared Dispatcher for off application
// Dispatcher inking support.
//
// Copyright (C) 2003-2004 by Microsoft Corporation. All rights reserved.
//
//---------------------------------------------------------------------------
using System;
using System.Diagnostics;
using System.Collections.Specialized;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Input;
using System.Windows.Media;
using System.Threading;
using System.Windows.Threading;
using MS.Utility;
using System.Security;
using System.Security.Permissions;
using MS.Internal;
namespace System.Windows.Input.StylusPlugIns
{
///
/// Manager for the Dispatcher.ShutdownStarted event.
///
// Note: this class should have the same visibility (public / internal /
// private) as the event it manages. If the event is not public, change
// the visibility of this class accordingly.
internal sealed class DispatcherShutdownStartedEventManager : WeakEventManager
{
#region Constructors
//
// Constructors
//
private DispatcherShutdownStartedEventManager()
{
}
#endregion Constructors
#region Public Methods
//
// Public Methods
//
///
/// Add a listener to the given source's event.
///
///
/// Critical: Called only by SecurityCritical code DynamicRendererThreadManager::ctor
///
[SecurityCritical]
public static void AddListener(Dispatcher source, IWeakEventListener listener)
{
CurrentManager.ProtectedAddListener(source, listener);
}
#endregion Public Methods
#region Protected Methods
//
// Protected Methods
//
///
/// Listen to the given source for the event.
///
protected override void StartListening(object source)
{
Dispatcher typedSource = (Dispatcher)source;
typedSource.ShutdownStarted += new EventHandler(OnShutdownStarted);
}
///
/// Stop listening to the given source for the event.
///
protected override void StopListening(object source)
{
Dispatcher typedSource = (Dispatcher)source;
typedSource.ShutdownStarted -= new EventHandler(OnShutdownStarted);
}
#endregion Protected Methods
#region Private Properties
//
// Private Properties
//
///
/// get the event manager for the current thread
///
///
/// Critical: Called only by SecurityCritical code DynamicRendererThreadManager::ctor
///
private static DispatcherShutdownStartedEventManager CurrentManager
{
[SecurityCritical]
get
{
Type managerType = typeof(DispatcherShutdownStartedEventManager);
DispatcherShutdownStartedEventManager manager = (DispatcherShutdownStartedEventManager)GetCurrentManager(managerType);
// at first use, create and register a new manager
if (manager == null)
{
manager = new DispatcherShutdownStartedEventManager();
SetCurrentManager(managerType, manager);
}
return manager;
}
}
#endregion Private Properties
#region Private Methods
//
// Private Methods
//
// event handler for ShutdownStarted event
private void OnShutdownStarted(object sender, EventArgs args)
{
DeliverEvent(sender, args);
}
#endregion Private Methods
}
/////////////////////////////////////////////////////////////////////////
///
/// This class provides a Dispatcher on a shared thread for use in real time inking. Each
/// instance of this class must call Dispose() in order to have this thread shut
/// down properly.
///
internal class DynamicRendererThreadManager : IWeakEventListener, IDisposable
{
[ThreadStatic]
private static WeakReference _tsDRTMWeakRef;
internal static DynamicRendererThreadManager GetCurrentThreadInstance()
{
// Create the threadstatic DynamicRendererThreadManager as needed for calling thread.
// It only creates one
if (_tsDRTMWeakRef == null || _tsDRTMWeakRef.Target == null)
{
_tsDRTMWeakRef = new WeakReference(new DynamicRendererThreadManager());
}
return _tsDRTMWeakRef.Target as DynamicRendererThreadManager;
}
private volatile Dispatcher __inkingDispatcher; // Can be accessed from multiple threads.
private bool _disposed;
///
/// Private contructor called by static method so that we can only ever create one of these per thread!
///
///
/// Critical: This code creates a singleton thread that runs it own Dispatcher pump via InkingThreadProc.
/// Called by DynamicRenderer.CreateRealTimeVisuals().
/// TreatAsSafe: Calling this over and over can only create one shared thread with its own dispatcher which is at
/// the most a nuisance.
///
[SecurityCritical,SecurityTreatAsSafe]
private DynamicRendererThreadManager()
{
// Create the thread
DynamicRendererThreadManagerWorker worker = new DynamicRendererThreadManagerWorker();
__inkingDispatcher = worker.StartUpAndReturnDispatcher();
// NTRAID:WINDOWSOS#1877251-2006/10/10-WAYNEZEN,
// Add a weak listener to the application dispatcher's ShutdownStarted event. So we can
// shut down our dynamic rendering thread gracefully when the app dispatcher is being shut down.
DispatcherShutdownStartedEventManager.AddListener(Dispatcher.CurrentDispatcher, this);
Debug.Assert(__inkingDispatcher != null); // We should have a valid ref here
}
// Finalizer - clean up thread
~DynamicRendererThreadManager()
{
Dispose(false);
}
///
/// IDisposable.Dispose implementation.
///
public void Dispose()
{
// NOTE: This object is internal to the DynamicRenderer and you really shouldn't call this.
// It's was added to be consistent with .NET design guidelines.
// Just let the finalizer do any required clean up work!
Dispose(true);
GC.SuppressFinalize(this);
}
///
/// Handle events from the centralized event table
///
bool IWeakEventListener.ReceiveWeakEvent(Type managerType, object sender, EventArgs args)
{
//NOTE: if DispatcherShutdownStartedEventManager is updated to listen
//to anything besides ShutdownStarted, you should disambiguate the event here
if (managerType == typeof(DispatcherShutdownStartedEventManager))
{
OnAppDispatcherShutdown(sender, args);
}
else
{
return false; // unrecognized event
}
return true;
}
///
/// The app dispatcher Shutdown Handler
///
///
///
private void OnAppDispatcherShutdown(object sender, EventArgs e)
{
Dispatcher inkingDispatcher = __inkingDispatcher;
// Return from here if the inking dispathcer is gone already.
if (inkingDispatcher == null)
return;
// Mashal the Dispose call, which will shut down our Dynamic rendering thread, to the inking dispatcher.
inkingDispatcher.Invoke(DispatcherPriority.Send,
(DispatcherOperationCallback)delegate(object unused)
{
Dispose();
return null;
},
null);
}
///
/// Handles disposing of internal object data.
///
/// true when freeing managed and unmanaged resources; false if freeing just unmanaged resources.
///
/// Critical - Calls SecurityCritical method Dispatcher.CriticalShutdown.
/// Called by Dispose() and Finalizer.
/// TreatAsSafe - No critical data returned or accepted as input.
///
[SecurityCritical, SecurityTreatAsSafe]
void Dispose(bool disposing)
{
if(!_disposed)
{
_disposed = true;
// Free up the thread
if (__inkingDispatcher != null && !Environment.HasShutdownStarted)
{
try
{
__inkingDispatcher.CriticalInvokeShutdown();
}
catch(System.ComponentModel.Win32Exception e)
{
if (e.NativeErrorCode != 1400) // ERROR_INVALID_WINDOW_HANDLE
{
// This is an unlocalized string but it only prints on the Debug Console
Debug.WriteLine(String.Format("Dispatcher.CriticalInvokeShutdown() Failed. Error={0}", e.NativeErrorCode));
}
}
finally
{
__inkingDispatcher = null;
}
}
}
GC.KeepAlive(this);
}
///
/// Gets the inking thread dispatcher.
///
internal Dispatcher ThreadDispatcher
{
get
{
return __inkingDispatcher;
}
}
// Helper class to manager the thread startup and thread proc. Needed in order to allow
// the DynamicRendererThreadManager to get garbage collected.
private class DynamicRendererThreadManagerWorker
{
private Dispatcher _dispatcher;
private AutoResetEvent _startupCompleted;
///
/// Constructor.
///
internal DynamicRendererThreadManagerWorker()
{
}
///
/// Critical: This code creates a singleton thread that runs it own Dispatcher pump via InkingThreadProc.
/// Called by DynamicRendererThreadManager constructor.
/// the most a nuisance.
///
[SecurityCritical]
internal Dispatcher StartUpAndReturnDispatcher()
{
_startupCompleted = new AutoResetEvent(false);
Thread inkingThread = new Thread(new ThreadStart(InkingThreadProc));
inkingThread.SetApartmentState(ApartmentState.STA);
inkingThread.IsBackground = true; // Don't keep process alive if this thread still running.
inkingThread.Start();
_startupCompleted.WaitOne();
_startupCompleted.Close();
_startupCompleted = null;
return _dispatcher;
}
///
/// Critical: This code calls into Dispatcher.Run on a given thread
///
[SecurityCritical]
public void InkingThreadProc()
{
Thread.CurrentThread.Name = "DynamicRenderer";
// Now make sure we create the dispatcher.
_dispatcher = Dispatcher.CurrentDispatcher;
// Now we can signal that everything is set up.
_startupCompleted.Set();
// Now start the dispatcher message loop for this thread.
Dispatcher.Run();
}
}
}
}
// 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
- CodeDelegateInvokeExpression.cs
- WindowsGrip.cs
- XmlCodeExporter.cs
- PropertyFilterAttribute.cs
- UdpContractFilterBehavior.cs
- XmlWhitespace.cs
- WeakReferenceList.cs
- DataControlFieldHeaderCell.cs
- ImageDrawing.cs
- ValueType.cs
- CmsInterop.cs
- ContainsRowNumberChecker.cs
- EntityContainerEntitySetDefiningQuery.cs
- DialogResultConverter.cs
- arclist.cs
- CryptoStream.cs
- InternalTransaction.cs
- ApplicationDirectory.cs
- DesignerDataTable.cs
- StreamedFramingRequestChannel.cs
- OrderedDictionary.cs
- WrapPanel.cs
- Point3DIndependentAnimationStorage.cs
- TypeSystem.cs
- StringSorter.cs
- TimeSpanConverter.cs
- glyphs.cs
- ProfilePropertySettings.cs
- JavascriptCallbackBehaviorAttribute.cs
- ResourceContainer.cs
- ReturnType.cs
- TriggerActionCollection.cs
- TableRow.cs
- CodeTryCatchFinallyStatement.cs
- AttributeEmitter.cs
- ZipIOExtraFieldZip64Element.cs
- SystemNetHelpers.cs
- FunctionQuery.cs
- MappingSource.cs
- IsolationInterop.cs
- HandlerMappingMemo.cs
- MobileTextWriter.cs
- CommonRemoteMemoryBlock.cs
- SetterBaseCollection.cs
- ProfilePropertyNameValidator.cs
- HttpCapabilitiesEvaluator.cs
- Types.cs
- DelayedRegex.cs
- AcceptorSessionSymmetricMessageSecurityProtocol.cs
- XmlTextReader.cs
- WebControl.cs
- ControlBuilderAttribute.cs
- CryptoApi.cs
- WorkflowApplicationCompletedEventArgs.cs
- ReadOnlyCollection.cs
- TypeLibConverter.cs
- DataSourceGeneratorException.cs
- PreviewKeyDownEventArgs.cs
- ValidationRule.cs
- Group.cs
- mediaeventshelper.cs
- IdentityReference.cs
- Parser.cs
- MessageDescription.cs
- InheritablePropertyChangeInfo.cs
- CompilerParameters.cs
- EventWaitHandle.cs
- HttpServerUtilityBase.cs
- KnowledgeBase.cs
- CookieHandler.cs
- SelectionRange.cs
- SettingsSavedEventArgs.cs
- PolyBezierSegmentFigureLogic.cs
- Pens.cs
- DesignerAttribute.cs
- WmlSelectionListAdapter.cs
- HighlightComponent.cs
- XmlParserContext.cs
- GPPOINT.cs
- TagMapInfo.cs
- _BaseOverlappedAsyncResult.cs
- InternalPermissions.cs
- WindowsGraphics.cs
- UnitySerializationHolder.cs
- peernodestatemanager.cs
- XmlMemberMapping.cs
- SqlResolver.cs
- ProfileSettings.cs
- Pipe.cs
- ArrayConverter.cs
- NativeMethodsOther.cs
- SmiContext.cs
- MemoryFailPoint.cs
- SetIndexBinder.cs
- MessageBox.cs
- ObjectToIdCache.cs
- HyperLinkColumn.cs
- TextBreakpoint.cs
- QueryAccessibilityHelpEvent.cs
- MultipartContentParser.cs