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
- FileDialog.cs
- ConstraintStruct.cs
- QuaternionConverter.cs
- DataGridViewRowCancelEventArgs.cs
- TreeViewAutomationPeer.cs
- CodeMethodReturnStatement.cs
- CircleHotSpot.cs
- RecordConverter.cs
- Gdiplus.cs
- BuilderInfo.cs
- Symbol.cs
- JavaScriptObjectDeserializer.cs
- SamlAudienceRestrictionCondition.cs
- SafeTokenHandle.cs
- DocumentViewerBase.cs
- BadImageFormatException.cs
- ExecutedRoutedEventArgs.cs
- RemoteWebConfigurationHost.cs
- OdbcPermission.cs
- HyperLinkStyle.cs
- InstancePersistenceEvent.cs
- SimpleFieldTemplateUserControl.cs
- DefaultMergeHelper.cs
- BeginStoryboard.cs
- CompilerTypeWithParams.cs
- AspNetSynchronizationContext.cs
- AttachInfo.cs
- XPathSelfQuery.cs
- WebCategoryAttribute.cs
- ActivityDesignerResources.cs
- RelativeSource.cs
- DeferredTextReference.cs
- RepeatBehavior.cs
- Walker.cs
- ConfigurationPropertyAttribute.cs
- SubMenuStyle.cs
- SupportsEventValidationAttribute.cs
- VectorCollection.cs
- ValueHandle.cs
- StreamWithDictionary.cs
- Tuple.cs
- MetadataCache.cs
- CultureSpecificStringDictionary.cs
- EdmItemCollection.OcAssemblyCache.cs
- InkPresenterAutomationPeer.cs
- UiaCoreApi.cs
- ToolStripArrowRenderEventArgs.cs
- PinnedBufferMemoryStream.cs
- SchemaContext.cs
- DebugControllerThread.cs
- ConfigXmlElement.cs
- PlaceHolder.cs
- XLinq.cs
- LicenseProviderAttribute.cs
- returneventsaver.cs
- SafeBitVector32.cs
- DependencyObjectPropertyDescriptor.cs
- TemplateXamlTreeBuilder.cs
- XmlSchemaGroupRef.cs
- PathTooLongException.cs
- StringCollectionMarkupSerializer.cs
- HeaderUtility.cs
- AttachedPropertyBrowsableAttribute.cs
- Exceptions.cs
- AnchorEditor.cs
- ToolStripOverflowButton.cs
- TextServicesManager.cs
- PersistenceTypeAttribute.cs
- CounterSampleCalculator.cs
- CachedFontFace.cs
- TemplatePropertyEntry.cs
- CultureTable.cs
- HWStack.cs
- SymmetricKeyWrap.cs
- httpserverutility.cs
- SqlNotificationRequest.cs
- XPathSelfQuery.cs
- ParserStreamGeometryContext.cs
- XmlElementAttributes.cs
- ProfileSettingsCollection.cs
- ColumnMapVisitor.cs
- Accessors.cs
- XmlTextReaderImplHelpers.cs
- Lease.cs
- EventLogSession.cs
- DataErrorValidationRule.cs
- DefaultPropertyAttribute.cs
- PreviewPageInfo.cs
- ViewGenResults.cs
- DataGridViewRowPostPaintEventArgs.cs
- UnicastIPAddressInformationCollection.cs
- XmlSchemaComplexContentRestriction.cs
- CheckBox.cs
- TypeDescriptionProvider.cs
- ConditionChanges.cs
- UnknownWrapper.cs
- HttpHandlerAction.cs
- DataGridLengthConverter.cs
- TextTreeInsertUndoUnit.cs
- GeometryDrawing.cs