[英]WCF dynamic proxy with NetNamedPipeBinding not being garbage collected
由於幾個小時后找不到合適的答案,因此將其張貼在這里。
我有一個帶有共享接口(IService)庫和動態創建的代理(使用CreateChannel創建)的WPF / WCF應用程序。 主要問題是代理沒有被關閉/處置,在第200個服務呼叫中出現此異常:
系統達到了節流閥“ MaxConcurrentSessions”的限制。 該油門的限制設置為200。可以通過修改serviceThrottle元素中的屬性“ maxConcurrentSessions”或通過修改行為ServiceThrottlingBehavior的“ MaxConcurrentSessions”屬性來更改油門值。
有趣的是,同一代理可以與BasicHttpBinding一起正常工作!
似乎NetNamedPipeBinding代理沒有被關閉並自動處置。 以下是一些客戶端代碼段。
// creation of ChannelFactory - only one for each service interface
public static ChannelFactory<T> CreateChannelFactory(string serviceAddress)
{
Binding binding = new NetNamedPipeBinding()
{
// setting quotas and timeouts
};
ChannelFactory<T> factory = new ChannelFactory<T>(binding, new EndpointAddress(serviceAddress));
factory.Endpoint.Behaviors.Add(new AuthenticationBehavior()); // custom IEndpointBehavior
foreach (OperationDescription op in factory.Endpoint.Contract.Operations)
{
DataContractSerializerOperationBehavior dataContractBehavior = op.Behaviors.Find<DataContractSerializerOperationBehavior>() as DataContractSerializerOperationBehavior;
if (dataContractBehavior != null)
{
dataContractBehavior.MaxItemsInObjectGraph = 2147483647;
}
}
return factory;
}
public static T GetService()
{
// simplified - actually holding a collection of CFs and creating each factory only once
return ChannelFactoryHelper<T>.CreateChannelFactory(serviceAddress).CreateChannel();
}
// creation of the proxy - new for each WCF call
IService svc = ServiceHelper<IService>.GetService();
... // calling the service
您可以看到我沒有使用“ using”語句,因為代理未實現IDisposable。 第一個問題是,我該怎么做。 在客戶端,我使用IService作為代理類型。 如果我希望IService是IDisposable的,則必須在服務端實現dispose方法-因為我的服務實現了IService。 這似乎不合邏輯-調用服務方法來處置該服務...
由於最好不要將服務調用的所有代碼都更改為“ using”:當不再使用代理時,有沒有辦法自動處置代理? 為什么不能自動完成? 請注意,我正在使用自定義IExtensionBehavior-這可能是原因嗎?
任何幫助,將不勝感激。 謝謝!
首先,您會發現從CreateChannel
方法返回的服務代理對象確實實現了IDisposable
,因為IClientChannel
從IDisposable
派生的。 但是,您不應使用標准的using塊來利用此功能,因為如果在使用通道時發生故障,則在右括號中會發生難以診斷的異常。
與在每種服務代理類型的包裝器中費力地顯式實現IDisposable相比,您可能會發現以下模式的一些變體是一種改進。 您可以在接受委托的通用函數( Action<IService>
)中執行模式,以執行“調用服務”位。
IService svc;
try
{
// creation of the proxy - new for each WCF call
svc = ServiceHelper<IService>.GetService();
... // calling the service
myDelegateDoingStuffWithService(svc);
}
finally
{
try
{
((ICommunicationObject)svc).Close();
}
catch (CommunicationException ex)
{
((ICommunicationObject)svc).Abort();
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.