Code:
/ WCF / WCF / 3.5.30729.1 / untmp / Orcas / SP / ndp / cdf / src / WCF / ServiceModel / System / ServiceModel / Dispatcher / ConcurrencyBehavior.cs / 1 / ConcurrencyBehavior.cs
//------------------------------------------------------------------------------ // Copyright (c) Microsoft Corporation. All rights reserved. //----------------------------------------------------------------------------- namespace System.ServiceModel.Dispatcher { using System; using System.ServiceModel; using System.ServiceModel.Channels; using System.Threading; using System.Collections.Generic; class ConcurrencyBehavior { ConcurrencyMode mode; bool supportsTransactedBatch; internal ConcurrencyBehavior(DispatchRuntime runtime) { this.mode = runtime.ConcurrencyMode; this.supportsTransactedBatch = ConcurrencyBehavior.SupportsTransactedBatch(runtime.ChannelDispatcher); } static bool SupportsTransactedBatch(ChannelDispatcher channelDispatcher) { return channelDispatcher.IsTransactedReceive && (channelDispatcher.MaxTransactedBatchSize > 0); } internal bool IsConcurrent(ref MessageRpc rpc) { return IsConcurrent(this.mode, rpc.Channel.HasSession, this.supportsTransactedBatch); } internal static bool IsConcurrent(ConcurrencyMode mode, bool hasSession, bool supportsTransactedBatch) { return !supportsTransactedBatch && ((mode != ConcurrencyMode.Single) || !hasSession); } internal static bool IsConcurrent(ChannelDispatcher runtime, bool hasSession) { if (ConcurrencyBehavior.SupportsTransactedBatch(runtime)) { return false; } if (!hasSession) { return true; } foreach (EndpointDispatcher endpointDispatcher in runtime.Endpoints) { if (endpointDispatcher.DispatchRuntime.ConcurrencyMode != ConcurrencyMode.Single) { return true; } } return false; } internal void LockInstance(ref MessageRpc rpc) { if (this.mode != ConcurrencyMode.Multiple) { ConcurrencyInstanceContextFacet resource = rpc.InstanceContext.Concurrency; lock (rpc.InstanceContext.ThisLock) { if (!resource.Locked) { resource.Locked = true; } else { MessageRpcWaiter waiter = new MessageRpcWaiter(rpc.Pause()); resource.EnqueueNewMessage(waiter); } } if (this.mode == ConcurrencyMode.Reentrant) { rpc.OperationContext.IsServiceReentrant = true; } } } internal void UnlockInstance(ref MessageRpc rpc) { if (this.mode != ConcurrencyMode.Multiple) { ConcurrencyBehavior.UnlockInstance(rpc.InstanceContext); } } internal static void UnlockInstanceBeforeCallout(OperationContext operationContext) { if (operationContext != null && operationContext.IsServiceReentrant) { ConcurrencyBehavior.UnlockInstance(operationContext.InstanceContext); } } static void UnlockInstance(InstanceContext instanceContext) { ConcurrencyInstanceContextFacet resource = instanceContext.Concurrency; lock (instanceContext.ThisLock) { if (resource.HasWaiters) { IWaiter nextWaiter = resource.DequeueWaiter(); nextWaiter.Signal(); } else { //We have no pending Callouts and no new Messages to process resource.Locked = false; } } } internal static void LockInstanceAfterCallout(OperationContext operationContext) { if (operationContext != null) { InstanceContext instanceContext = operationContext.InstanceContext; if (operationContext.IsServiceReentrant) { ConcurrencyInstanceContextFacet resource = instanceContext.Concurrency; ThreadWaiter waiter = null; lock (instanceContext.ThisLock) { if (!resource.Locked) { resource.Locked = true; } else { waiter = new ThreadWaiter(); resource.EnqueueCalloutMessage(waiter); } } if (waiter != null) { waiter.Wait(); } } } } internal interface IWaiter { void Signal(); } class MessageRpcWaiter : IWaiter { IResumeMessageRpc resume; internal MessageRpcWaiter(IResumeMessageRpc resume) { this.resume = resume; } void IWaiter.Signal() { try { bool alreadyResumedNoLock; this.resume.Resume(out alreadyResumedNoLock); if (alreadyResumedNoLock) { DiagnosticUtility.DebugAssert("ConcurrencyBehavior resumed more than once for same call."); } } catch (Exception e) { if (DiagnosticUtility.IsFatal(e)) { throw; } throw DiagnosticUtility.ExceptionUtility.ThrowHelperCallback(e); } } } class ThreadWaiter : IWaiter { ManualResetEvent wait = new ManualResetEvent(false); void IWaiter.Signal() { this.wait.Set(); } internal void Wait() { this.wait.WaitOne(); this.wait.Close(); } } } internal class ConcurrencyInstanceContextFacet { internal bool Locked; QueuecalloutMessageQueue; Queue newMessageQueue; internal bool HasWaiters { get { return (((this.calloutMessageQueue != null) && (this.calloutMessageQueue.Count > 0)) || ((this.newMessageQueue != null) && (this.newMessageQueue.Count > 0))); } } ConcurrencyBehavior.IWaiter DequeueFrom(Queue queue) { ConcurrencyBehavior.IWaiter waiter = queue.Dequeue(); if (queue.Count == 0) { queue.TrimExcess(); } return waiter; } internal ConcurrencyBehavior.IWaiter DequeueWaiter() { // Finishing old work takes precedence over new work. if ((this.calloutMessageQueue != null) && (this.calloutMessageQueue.Count > 0)) { return this.DequeueFrom(this.calloutMessageQueue); } else { return this.DequeueFrom(this.newMessageQueue); } } internal void EnqueueNewMessage(ConcurrencyBehavior.IWaiter waiter) { if (this.newMessageQueue == null) this.newMessageQueue = new Queue (); this.newMessageQueue.Enqueue(waiter); } internal void EnqueueCalloutMessage(ConcurrencyBehavior.IWaiter waiter) { if (this.calloutMessageQueue == null) this.calloutMessageQueue = new Queue (); this.calloutMessageQueue.Enqueue(waiter); } } } // 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
- RelationshipEndMember.cs
- EventToken.cs
- AbstractSvcMapFileLoader.cs
- StringValidatorAttribute.cs
- ImageKeyConverter.cs
- ContextQuery.cs
- CultureInfo.cs
- DetailsViewDeletedEventArgs.cs
- KnownColorTable.cs
- SafeMemoryMappedFileHandle.cs
- LinkLabelLinkClickedEvent.cs
- PipelineDeploymentState.cs
- PropertyGridEditorPart.cs
- SymDocumentType.cs
- EntityDesignerDataSourceView.cs
- WorkflowDesignerMessageFilter.cs
- DbConnectionPoolOptions.cs
- Variable.cs
- StackOverflowException.cs
- BamlResourceContent.cs
- BitmapPalette.cs
- DataControlCommands.cs
- NetDataContractSerializer.cs
- NumericPagerField.cs
- DropSource.cs
- HostSecurityManager.cs
- ImageListImageEditor.cs
- DataGridViewRowContextMenuStripNeededEventArgs.cs
- ControlBindingsConverter.cs
- ContentPlaceHolder.cs
- Proxy.cs
- SqlRewriteScalarSubqueries.cs
- ChangePassword.cs
- PersonalizationStateInfoCollection.cs
- LambdaReference.cs
- RowTypeElement.cs
- CallSiteBinder.cs
- OdbcErrorCollection.cs
- ApplicationContext.cs
- VisualCollection.cs
- FlowDocumentFormatter.cs
- TraceHwndHost.cs
- TraceContextEventArgs.cs
- Section.cs
- QilNode.cs
- TransactionWaitAsyncResult.cs
- EpmSyndicationContentSerializer.cs
- GraphicsPathIterator.cs
- HealthMonitoringSectionHelper.cs
- InstanceStoreQueryResult.cs
- XmlSerializerFactory.cs
- ResourceContainer.cs
- TextFormatterImp.cs
- ScriptResourceAttribute.cs
- mil_commands.cs
- PeerUnsafeNativeCryptMethods.cs
- TdsEnums.cs
- RuntimeEnvironment.cs
- PackageDigitalSignature.cs
- SelectionPattern.cs
- BitmapData.cs
- PointLight.cs
- Input.cs
- CustomLineCap.cs
- BaseProcessProtocolHandler.cs
- OleDbParameterCollection.cs
- ColumnReorderedEventArgs.cs
- WindowsAuthenticationEventArgs.cs
- ServiceActivationException.cs
- ContextMenuAutomationPeer.cs
- Logging.cs
- UnwrappedTypesXmlSerializerManager.cs
- ConfigsHelper.cs
- DecimalStorage.cs
- COM2IManagedPerPropertyBrowsingHandler.cs
- DesignTimeTemplateParser.cs
- InputLangChangeEvent.cs
- WasAdminWrapper.cs
- _AcceptOverlappedAsyncResult.cs
- FacetValueContainer.cs
- EntityDataSourceWizardForm.cs
- OleAutBinder.cs
- ExitEventArgs.cs
- safesecurityhelperavalon.cs
- ResolveMatches11.cs
- EventTrigger.cs
- StringCollectionEditor.cs
- SchemaEntity.cs
- DependencyObject.cs
- FixedSOMTableCell.cs
- FlagsAttribute.cs
- FrugalList.cs
- BStrWrapper.cs
- MdImport.cs
- TimersDescriptionAttribute.cs
- SymbolEqualComparer.cs
- NetworkInformationPermission.cs
- SystemException.cs
- SqlCacheDependencyDatabase.cs
- SerializationHelper.cs