//------------------------------------------------------------ // Copyright (c) Microsoft Corporation. All rights reserved. //------------------------------------------------------------ namespace System.ServiceModel { using System.Collections.Generic; using System.Runtime; using System.ServiceModel.Channels; using System.ServiceModel.Diagnostics.Application; sealed class ChannelFactoryRef where TChannel : class { ChannelFactory channelFactory; int refCount = 1; public ChannelFactoryRef(ChannelFactory channelFactory) { this.channelFactory = channelFactory; } public void AddRef() { this.refCount++; } // The caller should call Close/Abort when the return value is true. public bool Release() { --this.refCount; Fx.Assert(this.refCount >= 0, "RefCount should not be less than zero."); if (this.refCount == 0) { return true; } return false; } public void Close(TimeSpan timeout) { this.channelFactory.Close(timeout); } public void Abort() { this.channelFactory.Abort(); } public ChannelFactory ChannelFactory { get { return this.channelFactory; } } } class ChannelFactoryRefCache : MruCache, ChannelFactoryRef> where TChannel : class { static EndpointTraitComparer DefaultEndpointTraitComparer = new EndpointTraitComparer(); readonly int watermark; class EndpointTraitComparer : IEqualityComparer> { public bool Equals(EndpointTrait x, EndpointTrait y) { if (x != null) { if (y != null) return x.Equals(y); return false; } if (y != null) return false; return true; } public int GetHashCode(EndpointTrait obj) { if (obj == null) return 0; return obj.GetHashCode(); } } public ChannelFactoryRefCache(int watermark) : base(watermark * 4 / 5, watermark, DefaultEndpointTraitComparer) { this.watermark = watermark; } protected override void OnSingleItemRemoved(ChannelFactoryRef item) { // Remove from cache. if (item.Release()) { item.Abort(); } if (TD.ClientBaseCachedChannelFactoryCountIsEnabled()) { TD.ClientBaseCachedChannelFactoryCount(this.Count, this.watermark, this); } } protected override void OnItemAgedOutOfCache(ChannelFactoryRef item) { if (TD.ClientBaseChannelFactoryAgedOutofCacheIsEnabled()) { TD.ClientBaseChannelFactoryAgedOutofCache(this.watermark, this); } } } }