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
- IdentitySection.cs
- CheckBoxBaseAdapter.cs
- ListMarkerSourceInfo.cs
- UriSection.cs
- TransformerInfo.cs
- SerializationStore.cs
- CompilationLock.cs
- SerTrace.cs
- XmlException.cs
- DetailsViewPageEventArgs.cs
- HttpDictionary.cs
- DataSourceCollectionBase.cs
- CrossSiteScriptingValidation.cs
- DBPropSet.cs
- IntPtr.cs
- UnSafeCharBuffer.cs
- DataGridViewCellPaintingEventArgs.cs
- DBAsyncResult.cs
- COM2TypeInfoProcessor.cs
- OdbcParameterCollection.cs
- GridViewAutomationPeer.cs
- MetadataExchangeClient.cs
- VirtualPathProvider.cs
- UIPermission.cs
- HyperLinkColumn.cs
- X509UI.cs
- Zone.cs
- SafeThreadHandle.cs
- CommandTreeTypeHelper.cs
- NetStream.cs
- BindingManagerDataErrorEventArgs.cs
- FreeFormDragDropManager.cs
- ListBox.cs
- DataGridViewRowErrorTextNeededEventArgs.cs
- EntityDataSourceView.cs
- TakeQueryOptionExpression.cs
- ValidationHelper.cs
- Popup.cs
- FormViewCommandEventArgs.cs
- AccessControlList.cs
- RowUpdatedEventArgs.cs
- xamlnodes.cs
- DataBoundLiteralControl.cs
- ExpandableObjectConverter.cs
- ProtocolsConfigurationEntry.cs
- CodeTypeDeclaration.cs
- DataView.cs
- FontFamilyConverter.cs
- NotifyInputEventArgs.cs
- ModelPropertyDescriptor.cs
- RadioButtonRenderer.cs
- nulltextcontainer.cs
- StandardOleMarshalObject.cs
- XmlSignificantWhitespace.cs
- CollectionViewSource.cs
- _DomainName.cs
- ReflectionTypeLoadException.cs
- TreeNodeClickEventArgs.cs
- AssemblyFilter.cs
- DbConnectionStringBuilder.cs
- SQLInt64Storage.cs
- StringConverter.cs
- HttpHandlerAction.cs
- OrthographicCamera.cs
- PolyLineSegment.cs
- DecoderExceptionFallback.cs
- VolatileResourceManager.cs
- DateBoldEvent.cs
- SignedXml.cs
- DataColumn.cs
- Quaternion.cs
- ColorTransformHelper.cs
- EventProviderWriter.cs
- SecondaryIndexList.cs
- ReadContentAsBinaryHelper.cs
- TextViewDesigner.cs
- DataGridRowClipboardEventArgs.cs
- Input.cs
- OutputCacheSettingsSection.cs
- XmlSchemaDatatype.cs
- Visual3D.cs
- CompressEmulationStream.cs
- EmptyEnumerator.cs
- SqlColumnizer.cs
- XpsS0ValidatingLoader.cs
- DelegateSerializationHolder.cs
- ToolStripPanelRow.cs
- ASCIIEncoding.cs
- ConditionalWeakTable.cs
- RoutedCommand.cs
- GenerateScriptTypeAttribute.cs
- SafePEFileHandle.cs
- ExpressionEditorAttribute.cs
- ObfuscationAttribute.cs
- RequestCachingSection.cs
- SafeLocalMemHandle.cs
- AttributeEmitter.cs
- BlockUIContainer.cs
- MembershipValidatePasswordEventArgs.cs
- ToolStripDropTargetManager.cs