Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / clr / src / BCL / System / Threading / SynchronizationContext.cs / 1305376 / SynchronizationContext.cs
// ==++== // // Copyright (c) Microsoft Corporation. All rights reserved. // // //[....] /*============================================================ ** ** Class: SynchronizationContext ** ** ** Purpose: Capture synchronization semantics for asynchronous callbacks ** ** ===========================================================*/ namespace System.Threading { using Microsoft.Win32.SafeHandles; using System.Security.Permissions; using System.Runtime.InteropServices; using System.Runtime.CompilerServices; #if FEATURE_CORRUPTING_EXCEPTIONS using System.Runtime.ExceptionServices; #endif // FEATURE_CORRUPTING_EXCEPTIONS using System.Runtime; using System.Runtime.Versioning; using System.Runtime.ConstrainedExecution; using System.Reflection; using System.Diagnostics.Contracts; internal struct SynchronizationContextSwitcher : IDisposable { internal SynchronizationContext savedSC; internal SynchronizationContext currSC; internal ExecutionContext _ec; public override bool Equals(Object obj) { if (obj == null || !(obj is SynchronizationContextSwitcher)) return false; SynchronizationContextSwitcher sw = (SynchronizationContextSwitcher)obj; return (this.savedSC == sw.savedSC && this.currSC == sw.currSC && this._ec == sw._ec); } public override int GetHashCode() { return ToString().GetHashCode(); } public static bool operator ==(SynchronizationContextSwitcher c1, SynchronizationContextSwitcher c2) { return c1.Equals(c2); } public static bool operator !=(SynchronizationContextSwitcher c1, SynchronizationContextSwitcher c2) { return !c1.Equals(c2); } public void Dispose() { Undo(); } [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] #if FEATURE_CORRUPTING_EXCEPTIONS [System.Security.SecuritySafeCritical] [HandleProcessCorruptedStateExceptions] // #endif // FEATURE_CORRUPTING_EXCEPTIONS internal bool UndoNoThrow() { if (_ec == null) { return true; } try { Undo(); } catch { return false; } return true; } [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] public void Undo() { if (_ec == null) { return; } ExecutionContext executionContext = Thread.CurrentThread.GetExecutionContextNoCreate(); if (_ec != executionContext) { throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_SwitcherCtxMismatch")); } if (currSC != _ec.SynchronizationContext) { throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_SwitcherCtxMismatch")); } Contract.Assert(executionContext != null, " ExecutionContext can't be null"); // restore the Saved [....] context as current executionContext.SynchronizationContext = savedSC; // can't reuse this anymore _ec = null; } } #if FEATURE_SYNCHRONIZATIONCONTEXT_WAIT [Flags] enum SynchronizationContextProperties { None = 0, RequireWaitNotification = 0x1 }; #endif [SecurityPermissionAttribute(SecurityAction.InheritanceDemand, Flags =SecurityPermissionFlag.ControlPolicy|SecurityPermissionFlag.ControlEvidence)] public class SynchronizationContext { #if FEATURE_SYNCHRONIZATIONCONTEXT_WAIT SynchronizationContextProperties _props = SynchronizationContextProperties.None; #endif public SynchronizationContext() { } #if FEATURE_SYNCHRONIZATIONCONTEXT_WAIT // protected so that only the derived [....] context class can enable these flags [System.Security.SecuritySafeCritical] // auto-generated protected void SetWaitNotificationRequired() { // Prepare the method so that it can be called in a reliable fashion when a wait is needed. // This will obviously only make the Wait reliable if the Wait method is itself reliable. The only thing // preparing the method here does is to ensure there is no failure point before the method execution begins. RuntimeHelpers.PrepareDelegate(new WaitDelegate(this.Wait)); _props |= SynchronizationContextProperties.RequireWaitNotification; } public bool IsWaitNotificationRequired() { return ((_props & SynchronizationContextProperties.RequireWaitNotification) != 0); } #endif public virtual void Send(SendOrPostCallback d, Object state) { d(state); } public virtual void Post(SendOrPostCallback d, Object state) { ThreadPool.QueueUserWorkItem(new WaitCallback(d), state); } ////// Optional override for subclasses, for responding to notification that operation is starting. /// public virtual void OperationStarted() { } ////// Optional override for subclasses, for responding to notification that operation has completed. /// public virtual void OperationCompleted() { } #if FEATURE_SYNCHRONIZATIONCONTEXT_WAIT // Method called when the CLR does a wait operation [System.Security.SecurityCritical] // auto-generated_required [CLSCompliant(false)] [PrePrepareMethod] public virtual int Wait(IntPtr[] waitHandles, bool waitAll, int millisecondsTimeout) { if (waitHandles == null) { throw new ArgumentNullException("waitHandles"); } Contract.EndContractBlock(); return WaitHelper(waitHandles, waitAll, millisecondsTimeout); } // Static helper to which the above method can delegate to in order to get the default // COM behavior. [System.Security.SecurityCritical] // auto-generated_required [CLSCompliant(false)] [PrePrepareMethod] [ResourceExposure(ResourceScope.None)] [MethodImplAttribute(MethodImplOptions.InternalCall)] [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] protected static extern int WaitHelper(IntPtr[] waitHandles, bool waitAll, int millisecondsTimeout); #endif // set SynchronizationContext on the current thread [System.Security.SecurityCritical] // auto-generated_required #if !FEATURE_CORECLR [TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")] #endif public static void SetSynchronizationContext(SynchronizationContext syncContext) { SetSynchronizationContext(syncContext, Thread.CurrentThread.ExecutionContext.SynchronizationContext); } [System.Security.SecurityCritical] // auto-generated #if FEATURE_CORRUPTING_EXCEPTIONS [HandleProcessCorruptedStateExceptions] // #endif // FEATURE_CORRUPTING_EXCEPTIONS internal static SynchronizationContextSwitcher SetSynchronizationContext(SynchronizationContext syncContext, SynchronizationContext prevSyncContext) { // get current execution context ExecutionContext ec = Thread.CurrentThread.ExecutionContext; // create a swticher SynchronizationContextSwitcher scsw = new SynchronizationContextSwitcher(); RuntimeHelpers.PrepareConstrainedRegions(); try { // attach the switcher to the exec context scsw._ec = ec; // save the current [....] context using the passed in value scsw.savedSC = prevSyncContext; // save the new [....] context also scsw.currSC = syncContext; // update the current [....] context to the new context ec.SynchronizationContext = syncContext; } catch { // Any exception means we just restore the old SyncCtx scsw.UndoNoThrow(); //No exception will be thrown in this Undo() throw; } // return switcher return scsw; } #if FEATURE_CORECLR // // This is a framework-internal method for Jolt's use. The problem is that SynchronizationContexts set inside of a reverse p/invoke // into an AppDomain are not persisted in that AppDomain; the next time the same thread calls into the same AppDomain, // the [....] context will be null. For Silverlight, this means that it's impossible to persist a [....] context on the UI thread, // since Jolt is constantly transitioning in and out of each control's AppDomain on that thread. // // So for Jolt we will track a special thread-static context, which *will* persist across calls from Jolt, and if the thread does not // have a [....] context set in its execution context we'll use the thread-static context instead. // // This will break any future work that requires SynchronizationContext.Current to be in [....] with the value // stored in a thread's ExecutionContext (wait notifications being one such example). If that becomes a problem, we will // need to rework this mechanism (which is one reason it's not being exposed publically). // [ThreadStatic] private static SynchronizationContext s_threadStaticContext; [System.Security.SecurityCritical] internal static void SetThreadStaticContext(SynchronizationContext syncContext) { s_threadStaticContext = syncContext; } #endif // Get the current SynchronizationContext on the current thread public static SynchronizationContext Current { #if !FEATURE_CORECLR [TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")] #endif get { SynchronizationContext context = null; ExecutionContext ec = Thread.CurrentThread.GetExecutionContextNoCreate(); if (ec != null) { context = ec.SynchronizationContext; } #if FEATURE_CORECLR // hack for Silverlight 2 beta 2. See comments on SetThreadStaticContext if (context == null) { context = s_threadStaticContext; } #endif return context; } } // helper to Clone this SynchronizationContext, public virtual SynchronizationContext CreateCopy() { // the CLR dummy has an empty clone function - no member data return new SynchronizationContext(); } #if FEATURE_SYNCHRONIZATIONCONTEXT_WAIT [System.Security.SecurityCritical] // auto-generated private static int InvokeWaitMethodHelper(SynchronizationContext syncContext, IntPtr[] waitHandles, bool waitAll, int millisecondsTimeout) { return syncContext.Wait(waitHandles, waitAll, millisecondsTimeout); } #endif } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- SecurityProtocolFactory.cs
- Oci.cs
- elementinformation.cs
- UInt16Converter.cs
- MemberListBinding.cs
- XamlRtfConverter.cs
- NameTable.cs
- followingquery.cs
- QuestionEventArgs.cs
- XmlChoiceIdentifierAttribute.cs
- LinkLabel.cs
- WorkflowService.cs
- XmlImplementation.cs
- CatalogZone.cs
- CellParaClient.cs
- HtmlListAdapter.cs
- Attributes.cs
- XPathSelfQuery.cs
- WebEncodingValidatorAttribute.cs
- InternalSafeNativeMethods.cs
- InstalledFontCollection.cs
- FolderBrowserDialog.cs
- VersionedStreamOwner.cs
- PolicyStatement.cs
- SR.cs
- SafeArrayRankMismatchException.cs
- PeerName.cs
- CompilationSection.cs
- EtwProvider.cs
- TextEndOfLine.cs
- UpDownBase.cs
- ModulesEntry.cs
- ToolStripDropDownItem.cs
- SamlAudienceRestrictionCondition.cs
- ButtonField.cs
- dataobject.cs
- IsolatedStorageFilePermission.cs
- InternalDuplexChannelFactory.cs
- ResolvedKeyFrameEntry.cs
- RichTextBox.cs
- ExpandCollapsePatternIdentifiers.cs
- CommandSet.cs
- StaticDataManager.cs
- StylusButtonEventArgs.cs
- RectKeyFrameCollection.cs
- DeclarativeConditionsCollection.cs
- RC2.cs
- XmlCountingReader.cs
- ColumnResizeUndoUnit.cs
- KoreanLunisolarCalendar.cs
- TablePatternIdentifiers.cs
- HwndProxyElementProvider.cs
- ComAdminInterfaces.cs
- DefinitionBase.cs
- ThreadAbortException.cs
- DataGridViewCellParsingEventArgs.cs
- FixedSOMTableCell.cs
- SqlBuilder.cs
- HwndMouseInputProvider.cs
- FirstMatchCodeGroup.cs
- PropertyChangedEventArgs.cs
- CustomWebEventKey.cs
- ObjectQuery_EntitySqlExtensions.cs
- StringDictionaryEditor.cs
- InputMethod.cs
- TextServicesCompartment.cs
- Int64.cs
- Documentation.cs
- TypeUtil.cs
- RecognizedWordUnit.cs
- GeneralTransform3D.cs
- PropertyPath.cs
- TextFormatterContext.cs
- InputReferenceExpression.cs
- RectAnimationBase.cs
- GeneralTransform3DCollection.cs
- FormsAuthenticationTicket.cs
- InputMethodStateChangeEventArgs.cs
- SchemaTableOptionalColumn.cs
- BaseValidator.cs
- TileModeValidation.cs
- AtlasWeb.Designer.cs
- NodeCounter.cs
- InputMethod.cs
- StreamHelper.cs
- DebuggerAttributes.cs
- MetaModel.cs
- ResXFileRef.cs
- PackageRelationshipSelector.cs
- ClientUriBehavior.cs
- ToolStripSystemRenderer.cs
- SharedConnectionWorkflowTransactionService.cs
- TranslateTransform.cs
- SslStream.cs
- ResourceExpressionEditor.cs
- KeyMatchBuilder.cs
- NeutralResourcesLanguageAttribute.cs
- DocumentViewerBaseAutomationPeer.cs
- DataContractJsonSerializerOperationFormatter.cs
- GridViewColumnHeaderAutomationPeer.cs