1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122
|
//------------------------------------------------------------
// 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<TChannel>
where TChannel : class
{
ChannelFactory<TChannel> channelFactory;
int refCount = 1;
public ChannelFactoryRef(ChannelFactory<TChannel> 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<TChannel> ChannelFactory
{
get
{
return this.channelFactory;
}
}
}
class ChannelFactoryRefCache<TChannel> : MruCache<EndpointTrait<TChannel>, ChannelFactoryRef<TChannel>>
where TChannel : class
{
static EndpointTraitComparer DefaultEndpointTraitComparer = new EndpointTraitComparer();
readonly int watermark;
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)
{
this.watermark = watermark;
}
protected override void OnSingleItemRemoved(ChannelFactoryRef<TChannel> item)
{
// Remove from cache.
if (item.Release())
{
item.Abort();
}
if (TD.ClientBaseCachedChannelFactoryCountIsEnabled())
{
TD.ClientBaseCachedChannelFactoryCount(this.Count, this.watermark, this);
}
}
protected override void OnItemAgedOutOfCache(ChannelFactoryRef<TChannel> item)
{
if (TD.ClientBaseChannelFactoryAgedOutofCacheIsEnabled())
{
TD.ClientBaseChannelFactoryAgedOutofCache(this.watermark, this);
}
}
}
}
|