Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / cdf / src / NetFx35 / System.WorkflowServices / System / Workflow / Runtime / Hosting / ChannelManagerService.cs / 1305376 / ChannelManagerService.cs
//------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------
namespace System.Workflow.Runtime.Hosting
{
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Diagnostics;
using System.Globalization;
using System.Runtime;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Description;
using System.Workflow.Activities;
using System.Workflow.ComponentModel;
public sealed class ChannelManagerService : WorkflowRuntimeService
{
const string IdleTimeoutSetting = "idleTimeout";
const string InfiniteTimeSpanValue = "infinite";
const string LeaseTimeoutSetting = "leaseTimeout";
const string MaxIdleChannelsPerEndpointSetting = "maxIdleChannelsPerEndpoint";
ChannelManager channelManager;
bool closed;
IList codeEndpoints;
ChannelPoolSettings settings;
public ChannelManagerService()
: this(new ChannelPoolSettings(), new List())
{
}
public ChannelManagerService(ChannelPoolSettings settings)
: this(settings, new List())
{
}
public ChannelManagerService(IList endpoints)
: this(new ChannelPoolSettings(), endpoints)
{
}
public ChannelManagerService(ChannelPoolSettings settings, IList endpoints)
{
if (settings == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("settings");
}
if (endpoints == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("endpoints");
}
this.settings = settings;
this.codeEndpoints = endpoints;
}
public ChannelManagerService(NameValueCollection parameters)
{
if (parameters == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("parameters");
}
ChannelPoolSettings channelPoolSettings = new ChannelPoolSettings();
foreach (string key in parameters.Keys)
{
if (string.IsNullOrEmpty(key))
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument(
SR2.GetString(SR2.Error_UnknownConfigurationParameter, key), "parameters");
}
else if (key.Equals(ChannelManagerService.IdleTimeoutSetting, StringComparison.OrdinalIgnoreCase))
{
try
{
channelPoolSettings.IdleTimeout =
ConvertToTimeSpan(parameters[ChannelManagerService.IdleTimeoutSetting]);
}
catch (FormatException ex)
{
ArgumentException exception = new ArgumentException(
SR2.GetString(SR2.Error_InvalidIdleTimeout, parameters[ChannelManagerService.IdleTimeoutSetting]),
"parameters",
ex);
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(exception);
}
}
else if (key.Equals(ChannelManagerService.LeaseTimeoutSetting, StringComparison.OrdinalIgnoreCase))
{
try
{
channelPoolSettings.LeaseTimeout =
ConvertToTimeSpan(parameters[ChannelManagerService.LeaseTimeoutSetting]);
}
catch (FormatException ex)
{
ArgumentException exception = new ArgumentException(
SR2.GetString(SR2.Error_InvalidLeaseTimeout, parameters[ChannelManagerService.LeaseTimeoutSetting]),
"parameters",
ex);
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(exception);
}
}
else if (key.Equals(ChannelManagerService.MaxIdleChannelsPerEndpointSetting, StringComparison.OrdinalIgnoreCase))
{
try
{
channelPoolSettings.MaxOutboundChannelsPerEndpoint =
Convert.ToInt32(parameters[ChannelManagerService.MaxIdleChannelsPerEndpointSetting], System.Globalization.CultureInfo.CurrentCulture);
}
catch (FormatException ex)
{
ArgumentException exception = new ArgumentException(
SR2.GetString(SR2.Error_InvalidMaxIdleChannelsPerEndpoint, parameters[ChannelManagerService.MaxIdleChannelsPerEndpointSetting]),
"parameters",
ex);
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(exception);
}
}
else
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument(
SR2.GetString(SR2.Error_UnknownConfigurationParameter, key), "parameters");
}
}
this.settings = channelPoolSettings;
this.codeEndpoints = new List();
}
protected internal override void Start()
{
base.Start();
this.channelManager = new ChannelManager(this.settings, this.codeEndpoints);
this.closed = false;
}
protected internal override void Stop()
{
base.Stop();
if (!this.closed && this.channelManager != null)
{
this.channelManager.Close();
}
this.closed = true;
}
internal static void ApplyLogicalChannelContext(LogicalChannel logicalChannel)
{
Fx.Assert(OperationContext.Current != null, "Can be called within a valid OperationContext Scope");
WorkflowTrace.Host.TraceEvent(TraceEventType.Verbose, 0,
"ChannelManagerService: updating context associated with logical channel {0}",
logicalChannel.InstanceId);
if (logicalChannel.Context != null)
{
new ContextMessageProperty(logicalChannel.Context).AddOrReplaceInMessageProperties(OperationContext.Current.OutgoingMessageProperties);
}
}
internal static TransientChannelTicket CreateTransientChannel(LogicalChannel logicalChannel)
{
DiagnosticUtility.DebugAssert(logicalChannel != null, "logical channel cannot be null");
ChannelFactory factory = null;
IChannel channel = null;
bool channelOpened = false;
try
{
factory = ChannelManagerHelpers.CreateChannelFactory(logicalChannel.ConfigurationName, logicalChannel.ContractType);
channel = ChannelManagerHelpers.CreateChannel(logicalChannel.ContractType, factory, logicalChannel.CustomAddress);
channelOpened = true;
}
finally
{
if (!channelOpened)
{
if (channel != null)
{
ChannelManagerHelpers.CloseCommunicationObject(channel);
}
if (factory != null)
{
ChannelManagerHelpers.CloseCommunicationObject(factory);
}
}
}
return new TransientChannelTicket(channel, factory);
}
internal static ChannelTicket Take(ActivityExecutionContext executionContext, Guid workflowId, LogicalChannel logicalChannel)
{
if (executionContext == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("executionContext");
}
if (workflowId == Guid.Empty)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("workflowId",
SR2.GetString(SR2.Error_Cache_InvalidWorkflowId));
}
if (logicalChannel == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("logicalChannel");
}
ChannelManagerService channelManager = executionContext.GetService();
ChannelTicket channel;
if (channelManager != null)
{
channel = channelManager.TakeChannel(workflowId, logicalChannel);
}
else
{
channel = ChannelManagerService.CreateTransientChannel(logicalChannel);
}
return channel;
}
internal static void UpdateLogicalChannelContext(LogicalChannel logicalChannel)
{
Fx.Assert(OperationContext.Current != null, "Can be called from valid OperationContextScope");
WorkflowTrace.Host.TraceEvent(TraceEventType.Verbose, 0,
"ChannelManagerService: updating context associated with logical channel {0}",
logicalChannel.InstanceId);
ContextMessageProperty contextMessageProperty;
MessageProperties properties = OperationContext.Current.IncomingMessageProperties;
if (properties != null && ContextMessageProperty.TryGet(properties, out contextMessageProperty))
{
logicalChannel.Context = contextMessageProperty.Context;
}
}
internal void ReturnChannel(PooledChannelTicket pooledChannel)
{
DiagnosticUtility.DebugAssert(pooledChannel != null, "pooled channel cannot be null");
if (pooledChannel == null)
{
return;
}
WorkflowTrace.Host.TraceEvent(
TraceEventType.Information, 0,
"ChannelManagerService: return channel for workflow instance {0}, logical channel {1}",
new object[] { pooledChannel.WorkflowId, pooledChannel.LogicalChannelId });
this.channelManager.ReturnChannel(pooledChannel.ChannelPoolKey, pooledChannel.PooledChannel);
}
internal PooledChannelTicket TakeChannel(Guid workflowId, LogicalChannel logicalChannel)
{
if (this.closed)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
new InvalidOperationException(SR2.GetString(SR2.Error_CannotProvideChannel_ServiceStopped, logicalChannel.ConfigurationName, logicalChannel.CustomAddress)));
}
if (workflowId == Guid.Empty)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("workflowId",
SR2.GetString(SR2.Error_Cache_InvalidWorkflowId));
}
if (logicalChannel == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("logicalChannel");
}
WorkflowTrace.Host.TraceEvent(TraceEventType.Information, 0, "ChannelManagerService: get channel for workflow instance {0}, logical channel {1}", new object[] { workflowId, logicalChannel.InstanceId });
string endpointName = logicalChannel.ConfigurationName;
Type contractType = logicalChannel.ContractType;
string customAddress = logicalChannel.CustomAddress;
ChannelPoolKey channelKey;
ChannelManager.PooledChannel channel = this.channelManager.TakeChannel(endpointName, contractType, customAddress, out channelKey);
if (channel == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
new InvalidOperationException(SR2.GetString(SR2.Error_CannotProvideChannel, logicalChannel.ConfigurationName, logicalChannel.CustomAddress)));
}
PooledChannelTicket pooledChannel = new PooledChannelTicket(this, channel, channelKey, workflowId, logicalChannel.InstanceId);
return pooledChannel;
}
TimeSpan ConvertToTimeSpan(string value)
{
if (string.Equals(value, ChannelManagerService.InfiniteTimeSpanValue, StringComparison.OrdinalIgnoreCase))
{
return TimeSpan.MaxValue;
}
return TimeSpan.Parse(value, CultureInfo.InvariantCulture);
}
internal abstract class ChannelTicket : IDisposable
{
bool disposed;
protected ChannelTicket()
{
}
public abstract IChannel Channel
{
get;
}
public void Dispose()
{
if (!this.disposed)
{
this.disposed = true;
this.Close();
}
}
protected virtual void Close()
{
}
}
internal class PooledChannelTicket : ChannelTicket
{
ChannelManager.PooledChannel channel;
ChannelPoolKey channelPoolKey;
Guid logicalChannelId;
ChannelManagerService service;
Guid workflowId;
public PooledChannelTicket(ChannelManagerService service, ChannelManager.PooledChannel channel, ChannelPoolKey channelPoolKey, Guid workflowId, Guid logicalChannelId)
: base()
{
this.service = service;
this.channel = channel;
this.channelPoolKey = channelPoolKey;
this.workflowId = workflowId;
this.logicalChannelId = logicalChannelId;
}
public override IChannel Channel
{
get
{
return this.channel.InnerChannel;
}
}
internal ChannelPoolKey ChannelPoolKey
{
get
{
return this.channelPoolKey;
}
}
internal Guid LogicalChannelId
{
get
{
return this.logicalChannelId;
}
}
internal ChannelManager.PooledChannel PooledChannel
{
get
{
return this.channel;
}
}
internal Guid WorkflowId
{
get
{
return this.workflowId;
}
}
protected override void Close()
{
DiagnosticUtility.DebugAssert(this.channel != null, "channel has been closed already.");
if (this.channel != null)
{
this.service.ReturnChannel(this);
this.channel = null;
}
}
}
internal class TransientChannelTicket : ChannelTicket
{
IChannel channel;
ChannelFactory factory;
public TransientChannelTicket(IChannel channel, ChannelFactory factory)
: base()
{
this.channel = channel;
this.factory = factory;
}
public override IChannel Channel
{
get
{
return this.channel;
}
}
protected override void Close()
{
if (this.channel != null)
{
ChannelManagerHelpers.CloseCommunicationObject(this.channel);
this.channel = null;
}
if (this.factory != null)
{
ChannelManagerHelpers.CloseCommunicationObject(this.factory);
this.factory = null;
}
}
}
}
}
// 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
- ImpersonateTokenRef.cs
- PageAsyncTask.cs
- BehaviorEditorPart.cs
- HtmlInputHidden.cs
- NameValueConfigurationElement.cs
- ReturnEventArgs.cs
- MessageHeaderException.cs
- AuthorizationRuleCollection.cs
- ThreadStartException.cs
- ConfigXmlText.cs
- SqlBooleanMismatchVisitor.cs
- SecurityContext.cs
- DataServiceConfiguration.cs
- AlgoModule.cs
- XmlBinaryWriter.cs
- WebPartTracker.cs
- CreateUserWizardStep.cs
- StickyNoteAnnotations.cs
- UnsafeMethods.cs
- DataTableClearEvent.cs
- FrameworkContentElement.cs
- PeerEndPoint.cs
- FunctionDefinition.cs
- ParamArrayAttribute.cs
- Events.cs
- RawUIStateInputReport.cs
- StringReader.cs
- StrongTypingException.cs
- XpsResourceDictionary.cs
- DataServiceSaveChangesEventArgs.cs
- MaskPropertyEditor.cs
- DesignerWebPartChrome.cs
- CheckoutException.cs
- CreateUserErrorEventArgs.cs
- TrustManager.cs
- TargetParameterCountException.cs
- NavigationPropertyAccessor.cs
- UnauthorizedAccessException.cs
- RegisteredExpandoAttribute.cs
- AppDomainFactory.cs
- DataObject.cs
- peersecurityelement.cs
- ButtonBase.cs
- XmlSchemaSimpleContent.cs
- CompletedAsyncResult.cs
- ClickablePoint.cs
- MethodBody.cs
- ZipIOExtraFieldPaddingElement.cs
- TagPrefixAttribute.cs
- SchemaImporter.cs
- Point3DKeyFrameCollection.cs
- ColumnMapVisitor.cs
- GC.cs
- JoinElimination.cs
- SmiMetaDataProperty.cs
- ListViewSelectEventArgs.cs
- URLIdentityPermission.cs
- ElementUtil.cs
- ThreadPool.cs
- ParentQuery.cs
- SQLBoolean.cs
- SafeHandle.cs
- UIElementCollection.cs
- RuleRefElement.cs
- HierarchicalDataBoundControl.cs
- XmlWhitespace.cs
- BitmapMetadataBlob.cs
- ConnectionPointGlyph.cs
- GenericPrincipal.cs
- SizeChangedEventArgs.cs
- DateTimeConstantAttribute.cs
- InvalidPrinterException.cs
- PermissionSet.cs
- ProcessHost.cs
- SimpleHandlerBuildProvider.cs
- BitmapEffectvisualstate.cs
- DynamicPropertyHolder.cs
- ChooseAction.cs
- ComboBox.cs
- Substitution.cs
- ValidationErrorCollection.cs
- _CookieModule.cs
- WebBaseEventKeyComparer.cs
- Converter.cs
- AdapterDictionary.cs
- DeploymentSectionCache.cs
- Parser.cs
- DPCustomTypeDescriptor.cs
- Reference.cs
- Base64Decoder.cs
- CollectionEditorDialog.cs
- SapiAttributeParser.cs
- AppSecurityManager.cs
- MeshGeometry3D.cs
- HeaderedItemsControl.cs
- MultiAsyncResult.cs
- HwndSourceParameters.cs
- SerializerDescriptor.cs
- ServiceNameCollection.cs
- HtmlPageAdapter.cs