| File: System\ServiceModel\ChannelFactoryRefCache.cs | Web Access |
| Project: src\src\System.ServiceModel.Primitives\src\System.ServiceModel.Primitives.csproj (System.ServiceModel.Primitives) |
// 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.Collections.Generic; using System.Runtime; namespace System.ServiceModel { internal sealed class ChannelFactoryRef<TChannel> where TChannel : class { private ChannelFactory<TChannel> _channelFactory; private int _refCount = 1; public ChannelFactoryRef(ChannelFactory<TChannel> channelFactory) { _channelFactory = channelFactory; } public void AddRef() { _refCount++; } // The caller should call Close/Abort when the return value is true. public bool Release() { --_refCount; Fx.Assert(_refCount >= 0, "RefCount should not be less than zero."); if (_refCount == 0) { return true; } return false; } public void Close(TimeSpan timeout) { _channelFactory.Close(timeout); } public void Abort() { _channelFactory.Abort(); } public ChannelFactory<TChannel> ChannelFactory { get { return _channelFactory; } } } internal class ChannelFactoryRefCache<TChannel> : MruCache<EndpointTrait<TChannel>, ChannelFactoryRef<TChannel>> where TChannel : class { private static EndpointTraitComparer DefaultEndpointTraitComparer = new EndpointTraitComparer(); private readonly int _watermark; private class EndpointTraitComparer : IEqualityComparer<EndpointTrait<TChannel>> { public bool Equals(EndpointTrait<TChannel> x, EndpointTrait<TChannel> y) { if (x != null) { if (y != null) return x.Equals(y); return false; } if (y != null) return false; return true; } public int GetHashCode(EndpointTrait<TChannel> obj) { if (obj == null) return 0; return obj.GetHashCode(); } } public ChannelFactoryRefCache(int watermark) : base(watermark * 4 / 5, watermark, DefaultEndpointTraitComparer) { _watermark = watermark; } protected override void OnSingleItemRemoved(ChannelFactoryRef<TChannel> item) { // Remove from cache. if (item.Release()) { item.Abort(); } if (WcfEventSource.Instance.ClientBaseCachedChannelFactoryCountIsEnabled()) { WcfEventSource.Instance.ClientBaseCachedChannelFactoryCount(Count, _watermark, this); } } protected override void OnItemAgedOutOfCache(ChannelFactoryRef<TChannel> item) { if (WcfEventSource.Instance.ClientBaseChannelFactoryAgedOutofCacheIsEnabled()) { WcfEventSource.Instance.ClientBaseChannelFactoryAgedOutofCache(_watermark, this); } } } }