Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / wpf / src / Core / CSharp / System / Windows / Input / Stylus / DynamicRendererThreadManager.cs / 1305600 / 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) { if (source == null) throw new ArgumentNullException("source"); if (listener == null) throw new ArgumentNullException("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
- ActivitySurrogateSelector.cs
- ProcessHostConfigUtils.cs
- BulletChrome.cs
- ExceptionHandlersDesigner.cs
- RightsManagementEncryptionTransform.cs
- HandlerFactoryWrapper.cs
- IIS7WorkerRequest.cs
- RuleDefinitions.cs
- ImportOptions.cs
- IResourceProvider.cs
- SudsCommon.cs
- TableCell.cs
- RNGCryptoServiceProvider.cs
- MobileTemplatedControlDesigner.cs
- MetaTable.cs
- Keywords.cs
- DelayedRegex.cs
- DetailsViewInsertedEventArgs.cs
- GiveFeedbackEventArgs.cs
- FixedTextSelectionProcessor.cs
- OracleCommandSet.cs
- SqlBulkCopy.cs
- WebConvert.cs
- LogicalExpressionEditor.cs
- VirtualPathData.cs
- SvcMapFile.cs
- KnownTypes.cs
- DataObject.cs
- TextHidden.cs
- BoundsDrawingContextWalker.cs
- CriticalExceptions.cs
- AnimationClockResource.cs
- PenThread.cs
- ConfigurationLocation.cs
- SystemIPInterfaceStatistics.cs
- SoapSchemaMember.cs
- Profiler.cs
- ConfigurationSectionCollection.cs
- MouseActionValueSerializer.cs
- RectIndependentAnimationStorage.cs
- PerformanceCounterManager.cs
- HashCodeCombiner.cs
- HostingEnvironment.cs
- LocalizableResourceBuilder.cs
- CodePageUtils.cs
- FormsAuthenticationUser.cs
- Constraint.cs
- XamlBrushSerializer.cs
- ValidatorCompatibilityHelper.cs
- ProfessionalColorTable.cs
- TemplateBuilder.cs
- InputDevice.cs
- ConstraintConverter.cs
- BoolExpressionVisitors.cs
- ScrollItemPatternIdentifiers.cs
- TypeElement.cs
- Debug.cs
- Page.cs
- Script.cs
- Property.cs
- CodeSnippetStatement.cs
- RequestContextBase.cs
- EncoderNLS.cs
- HyperLinkColumn.cs
- CqlWriter.cs
- MailSettingsSection.cs
- LocalizableResourceBuilder.cs
- ChineseLunisolarCalendar.cs
- VBCodeProvider.cs
- OdbcErrorCollection.cs
- OleDbWrapper.cs
- NavigationHelper.cs
- GlyphShapingProperties.cs
- IdnMapping.cs
- FormsAuthenticationConfiguration.cs
- IdentityManager.cs
- TextContainerHelper.cs
- Form.cs
- DrawingGroupDrawingContext.cs
- MenuCommandsChangedEventArgs.cs
- TextContainerHelper.cs
- ReadWriteSpinLock.cs
- PointConverter.cs
- XmlSigningNodeWriter.cs
- WindowsGraphicsWrapper.cs
- FeatureSupport.cs
- CollectionsUtil.cs
- IndexOutOfRangeException.cs
- ScriptingWebServicesSectionGroup.cs
- XPathChildIterator.cs
- CheckBox.cs
- TransformFinalBlockRequest.cs
- InteropBitmapSource.cs
- Vector3DValueSerializer.cs
- LicenseManager.cs
- XamlTypeWithExplicitNamespace.cs
- Win32Exception.cs
- AutoGeneratedFieldProperties.cs
- MethodBuilder.cs
- WebPartVerbCollection.cs