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
- objectquery_tresulttype.cs
- SoapHeaderAttribute.cs
- RootBuilder.cs
- StopRoutingHandler.cs
- DBParameter.cs
- AsmxEndpointPickerExtension.cs
- InplaceBitmapMetadataWriter.cs
- PlanCompilerUtil.cs
- WeakEventManager.cs
- SqlTriggerContext.cs
- ObjectDataSourceMethodEventArgs.cs
- EventTrigger.cs
- WrapPanel.cs
- BamlTreeNode.cs
- ImageMetadata.cs
- XmlElementAttribute.cs
- IriParsingElement.cs
- PeerPresenceInfo.cs
- RepeaterItemEventArgs.cs
- SqlIdentifier.cs
- HttpResponseBase.cs
- StartUpEventArgs.cs
- ServiceAuthorizationBehavior.cs
- HandlerFactoryWrapper.cs
- QueueProcessor.cs
- TransactionContextValidator.cs
- CommandConverter.cs
- TargetControlTypeCache.cs
- InvokeProviderWrapper.cs
- ConfigXmlReader.cs
- HtmlInputControl.cs
- DataControlFieldHeaderCell.cs
- XmlSchemaParticle.cs
- DataPager.cs
- XmlDownloadManager.cs
- InstanceKeyNotReadyException.cs
- XDRSchema.cs
- ProgressiveCrcCalculatingStream.cs
- WindowsButton.cs
- TimeSpanMinutesConverter.cs
- XmlSchemaGroupRef.cs
- FormViewInsertEventArgs.cs
- IndexedString.cs
- XmlSchemaGroup.cs
- ProviderSettingsCollection.cs
- RegisteredExpandoAttribute.cs
- XmlNamedNodeMap.cs
- SyndicationSerializer.cs
- _ShellExpression.cs
- Color.cs
- ItemCollection.cs
- SystemTcpStatistics.cs
- XmlDocumentFragment.cs
- ClrPerspective.cs
- RowUpdatedEventArgs.cs
- DateTimeOffsetStorage.cs
- ObjectStateEntry.cs
- RepeaterCommandEventArgs.cs
- ValidatingReaderNodeData.cs
- DynamicRendererThreadManager.cs
- CurrentChangedEventManager.cs
- FunctionParameter.cs
- HandlerFactoryCache.cs
- SoapCommonClasses.cs
- Label.cs
- GroupItem.cs
- EmptyEnumerable.cs
- PhysicalFontFamily.cs
- MethodBuilder.cs
- Event.cs
- DocobjHost.cs
- ListViewSelectEventArgs.cs
- SqlBulkCopy.cs
- CounterCreationData.cs
- EventLog.cs
- StatusBarItem.cs
- ViewKeyConstraint.cs
- TreeViewBindingsEditor.cs
- BitmapMetadataBlob.cs
- XmlHelper.cs
- FrameworkTemplate.cs
- TraversalRequest.cs
- UIElementIsland.cs
- CompleteWizardStep.cs
- ServiceHandle.cs
- Rfc2898DeriveBytes.cs
- OneWayChannelFactory.cs
- InputQueue.cs
- ToolbarAUtomationPeer.cs
- ColorAnimation.cs
- SiteIdentityPermission.cs
- ToolboxComponentsCreatedEventArgs.cs
- SqlBooleanMismatchVisitor.cs
- SubclassTypeValidatorAttribute.cs
- Run.cs
- RectAnimationBase.cs
- TripleDESCryptoServiceProvider.cs
- AbstractSvcMapFileLoader.cs
- XmlAnyElementAttribute.cs
- SmiConnection.cs