| File: FrameworkFork\System.ServiceModel\System\ServiceModel\Channels\ChannelFactoryBase.cs | Web Access |
| Project: src\src\dotnet-svcutil\lib\src\dotnet-svcutil-lib.csproj (dotnet-svcutil-lib) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. using System.Runtime; using System.Threading.Tasks; namespace System.ServiceModel.Channels { public abstract class ChannelFactoryBase : ChannelManagerBase, IChannelFactory { private TimeSpan _closeTimeout = ServiceDefaults.CloseTimeout; private TimeSpan _openTimeout = ServiceDefaults.OpenTimeout; private TimeSpan _receiveTimeout = ServiceDefaults.ReceiveTimeout; private TimeSpan _sendTimeout = ServiceDefaults.SendTimeout; protected ChannelFactoryBase() { } protected ChannelFactoryBase(IDefaultCommunicationTimeouts timeouts) { this.InitializeTimeouts(timeouts); } protected override TimeSpan DefaultCloseTimeout { get { return _closeTimeout; } } protected override TimeSpan DefaultOpenTimeout { get { return _openTimeout; } } protected override TimeSpan DefaultReceiveTimeout { get { return _receiveTimeout; } } protected override TimeSpan DefaultSendTimeout { get { return _sendTimeout; } } public virtual T GetProperty<T>() where T : class { if (typeof(T) == typeof(IChannelFactory)) { return (T)(object)this; } return default(T); } protected override void OnAbort() { } protected override IAsyncResult OnBeginClose(TimeSpan timeout, AsyncCallback callback, object state) { return new CompletedAsyncResult(callback, state); } protected internal override Task OnCloseAsync(TimeSpan timeout) { return TaskHelpers.CompletedTask(); } protected override void OnClose(TimeSpan timeout) { } protected override void OnEndClose(IAsyncResult result) { CompletedAsyncResult.End(result); } private void InitializeTimeouts(IDefaultCommunicationTimeouts timeouts) { if (timeouts != null) { _closeTimeout = timeouts.CloseTimeout; _openTimeout = timeouts.OpenTimeout; _receiveTimeout = timeouts.ReceiveTimeout; _sendTimeout = timeouts.SendTimeout; } } } public abstract class ChannelFactoryBase<TChannel> : ChannelFactoryBase, IChannelFactory<TChannel> { private CommunicationObjectManager<IChannel> _channels; protected ChannelFactoryBase() : this(null) { } protected ChannelFactoryBase(IDefaultCommunicationTimeouts timeouts) : base(timeouts) { _channels = new CommunicationObjectManager<IChannel>(this.ThisLock); } public TChannel CreateChannel(EndpointAddress address) { if (address == null) throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("address"); return this.InternalCreateChannel(address, address.Uri); } public TChannel CreateChannel(EndpointAddress address, Uri via) { if (address == null) throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("address"); if (via == null) throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("via"); return this.InternalCreateChannel(address, via); } private TChannel InternalCreateChannel(EndpointAddress address, Uri via) { this.ValidateCreateChannel(); TChannel channel = this.OnCreateChannel(address, via); bool success = false; try { _channels.Add((IChannel)(object)channel); success = true; } finally { if (!success) ((IChannel)(object)channel).Abort(); } return channel; } protected abstract TChannel OnCreateChannel(EndpointAddress address, Uri via); protected void ValidateCreateChannel() { ThrowIfDisposed(); if (this.State != CommunicationState.Opened) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(string.Format(SRServiceModel.ChannelFactoryCannotBeUsedToCreateChannels, this.GetType().ToString()))); } } protected override void OnAbort() { IChannel[] currentChannels = _channels.ToArray(); foreach (IChannel channel in currentChannels) channel.Abort(); _channels.Abort(); } protected override void OnClose(TimeSpan timeout) { IChannel[] currentChannels = _channels.ToArray(); TimeoutHelper timeoutHelper = new TimeoutHelper(timeout); foreach (IChannel channel in currentChannels) channel.Close(timeoutHelper.RemainingTime()); _channels.Close(timeoutHelper.RemainingTime()); } protected override IAsyncResult OnBeginClose(TimeSpan timeout, AsyncCallback callback, object state) { return new ChainedCloseAsyncResult(timeout, callback, state, _channels.BeginClose, _channels.EndClose, _channels.ToArray()); } protected override void OnEndClose(IAsyncResult result) { ChainedCloseAsyncResult.End(result); } } }