Code:
/ DotNET / DotNET / 8.0 / untmp / whidbey / REDBITS / ndp / clr / src / BCL / System / Threading / SynchronizationContext.cs / 2 / 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;
using System.Runtime.ConstrainedExecution;
using System.Reflection;
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);
}
///
void IDisposable.Dispose()
{
Undo();
}
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
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"));
}
BCLDebug.Assert(executionContext != null, " ExecutionContext can't be null");
// restore the Saved Sync context as current
executionContext.SynchronizationContext = savedSC;
// can't reuse this anymore
_ec = null;
}
}
public delegate void SendOrPostCallback(Object state);
[Flags]
enum SynchronizationContextProperties
{
None = 0,
RequireWaitNotification = 0x1
};
[SecurityPermissionAttribute(SecurityAction.InheritanceDemand, Flags =SecurityPermissionFlag.ControlPolicy|SecurityPermissionFlag.ControlEvidence)]
public class SynchronizationContext
{
SynchronizationContextProperties _props = SynchronizationContextProperties.None;
public SynchronizationContext()
{
}
// protected so that only the derived sync context class can enable these flags
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);
}
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()
{
}
// Method called when the CLR does a wait operation
[CLSCompliant(false)]
[PrePrepareMethod]
[SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags =SecurityPermissionFlag.ControlPolicy|SecurityPermissionFlag.ControlEvidence)]
public virtual int Wait(IntPtr[] waitHandles, bool waitAll, int millisecondsTimeout)
{
if (waitHandles == null)
{
throw new ArgumentNullException("waitHandles");
}
return WaitHelper(waitHandles, waitAll, millisecondsTimeout);
}
// Static helper to which the above method can delegate to in order to get the default
// COM behavior.
[CLSCompliant(false)]
[PrePrepareMethod]
[MethodImplAttribute(MethodImplOptions.InternalCall)]
[SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags =SecurityPermissionFlag.ControlPolicy|SecurityPermissionFlag.ControlEvidence),
ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
protected static extern int WaitHelper(IntPtr[] waitHandles, bool waitAll, int millisecondsTimeout);
// set SynchronizationContext on the current thread
[SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags =SecurityPermissionFlag.ControlPolicy|SecurityPermissionFlag.ControlEvidence)]
public static void SetSynchronizationContext(SynchronizationContext syncContext)
{
SetSynchronizationContext(syncContext, Thread.CurrentThread.ExecutionContext.SynchronizationContext);
}
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 sync context using the passed in value
scsw.savedSC = prevSyncContext;
// save the new sync context also
scsw.currSC = syncContext;
// update the current sync 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;
}
// Get the current SynchronizationContext on the current thread
public static SynchronizationContext Current
{
get
{
ExecutionContext ec = Thread.CurrentThread.GetExecutionContextNoCreate();
if (ec != null)
return ec.SynchronizationContext;
return null;
}
}
// helper to Clone this SynchronizationContext,
public virtual SynchronizationContext CreateCopy()
{
// the CLR dummy has an empty clone function - no member data
return new SynchronizationContext();
}
private static int InvokeWaitMethodHelper(SynchronizationContext syncContext, IntPtr[] waitHandles, bool waitAll, int millisecondsTimeout)
{
return syncContext.Wait(waitHandles, waitAll, millisecondsTimeout);
}
}
}
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- XPathSingletonIterator.cs
- SimpleHandlerFactory.cs
- TableCellCollection.cs
- CodeSnippetStatement.cs
- BindingWorker.cs
- NativeStructs.cs
- LayoutEngine.cs
- Transform.cs
- TypeConstant.cs
- SelectionGlyph.cs
- ToolStripDropDownClosingEventArgs.cs
- TypeUtils.cs
- ToolBarDesigner.cs
- Positioning.cs
- TextRangeEditLists.cs
- TextContainerHelper.cs
- BitArray.cs
- ICspAsymmetricAlgorithm.cs
- XmlWhitespace.cs
- EntityDataSourceColumn.cs
- ValidatorUtils.cs
- WSIdentityFaultException.cs
- ContextDataSourceContextData.cs
- CompressedStack.cs
- bindurihelper.cs
- QueryContinueDragEvent.cs
- SettingsBase.cs
- ThreadStaticAttribute.cs
- DataGridViewAutoSizeColumnsModeEventArgs.cs
- AddressHeader.cs
- PeerToPeerException.cs
- FacetDescriptionElement.cs
- SparseMemoryStream.cs
- TableItemStyle.cs
- SchemaImporter.cs
- CodeMemberMethod.cs
- MessageQueueException.cs
- AnimationLayer.cs
- HandledMouseEvent.cs
- cookiecollection.cs
- XMLSchema.cs
- DocumentAutomationPeer.cs
- ValidationResult.cs
- RunWorkerCompletedEventArgs.cs
- SqlDataSourceStatusEventArgs.cs
- TextControlDesigner.cs
- XmlBoundElement.cs
- Matrix3D.cs
- BookmarkScopeHandle.cs
- VSWCFServiceContractGenerator.cs
- COM2IProvidePropertyBuilderHandler.cs
- InstallerTypeAttribute.cs
- StringFreezingAttribute.cs
- DiagnosticTrace.cs
- TCPClient.cs
- PropertyGrid.cs
- ResourceReferenceExpressionConverter.cs
- MobileFormsAuthentication.cs
- BinaryWriter.cs
- SQLRoleProvider.cs
- PropertyPathWorker.cs
- ViewStateException.cs
- DoubleAnimationUsingPath.cs
- VerificationAttribute.cs
- filewebrequest.cs
- WindowsListViewItemCheckBox.cs
- ElementNotAvailableException.cs
- KerberosTicketHashIdentifierClause.cs
- RelAssertionDirectKeyIdentifierClause.cs
- DynamicDiscoveryDocument.cs
- DataGridViewLayoutData.cs
- SortExpressionBuilder.cs
- DataGridViewComboBoxCell.cs
- AuthenticateEventArgs.cs
- ChangeDirector.cs
- PaperSource.cs
- DataSourceCacheDurationConverter.cs
- ListView.cs
- ListViewEditEventArgs.cs
- FullTextBreakpoint.cs
- PropertyPanel.cs
- TcpSocketManager.cs
- RightNameExpirationInfoPair.cs
- UniformGrid.cs
- ProfileService.cs
- ListMarkerLine.cs
- TrackingStringDictionary.cs
- SystemColors.cs
- ListViewUpdateEventArgs.cs
- WebPartMovingEventArgs.cs
- JapaneseLunisolarCalendar.cs
- XmlBinaryReader.cs
- OdbcConnectionPoolProviderInfo.cs
- Group.cs
- XamlStream.cs
- TranslateTransform3D.cs
- SessionConnectionReader.cs
- Timer.cs
- SmtpReplyReaderFactory.cs
- SecurityDocument.cs