c# – 从另一个WCF服务中调用WCF服务时WCF内存泄漏
发布时间:2020-12-15 22:09:08 所属栏目:百科 来源:网络整理
导读:我注意到WCF应用程序中存在内存泄漏问题,并设法在一个简单的程序中复制它.从另一个WCF服务中调用WCF服务时会出现此问题. 在下面的示例中,我有两个服务A和B.当我在服务A上调用DoWork方法时,它又调用服务B的DoWork方法. 在下面的示例中,我每次都创建一个新的Ch
我注意到WCF应用程序中存在内存泄漏问题,并设法在一个简单的程序中复制它.从另一个WCF服务中调用WCF服务时会出现此问题.
在下面的示例中,我有两个服务A和B.当我在服务A上调用DoWork方法时,它又调用服务B的DoWork方法. 在下面的示例中,我每次都创建一个新的ChannelFactory,使用它打开一个通道,调用DoWork,然后在最后处理通道和工厂.这样,进程就会开始泄漏内存. 如果我设置其中一个或两个调用,每次重复使用相同的ChannelFactory(注释并取消注释示例中标记的行),泄漏就会停止. 如果我每次调用服务A时都继续创建一个新的ChannelFactory,但是空白了ServiceA的DoWork方法(因此它不会调用ServiceB),则不会发生泄漏. 我正在运行针对.NET 3.5的程序.奇怪的是,如果我切换到.NET 4,4.5或4.5.1,该过程会更快地泄漏内存. 任何人都可以理解为什么会这样,也许可以解决它(或至少解决它)? 示例代码如下: using System; using System.ServiceModel; namespace memoryleak { internal class Program { private static void Main() { using (var hostA = new ServiceHost(new ServiceA(),new Uri("net.pipe://localhost"))) using (var hostB = new ServiceHost(new ServiceB(),new Uri("net.pipe://localhost"))) { hostA.AddServiceEndpoint(typeof (ContractA),new NetNamedPipeBinding(),"test_service_a"); hostA.Open(); hostB.AddServiceEndpoint(typeof (ContractB),"test_service_b"); hostB.Open(); while(true)dowork(); } } //CALLING SERVICE A //uncomment the following line to reuse the same ChannelFactory each time //private static readonly ChannelFactory<ContractA> pipeFactory=new ChannelFactory<ContractA>(new NetNamedPipeBinding(),new EndpointAddress("net.pipe://localhost/test_service_a")); private static void dowork() { //comment the following line to reuse the same ChannelFactory each time var pipeFactory = new ChannelFactory<ContractA>(new NetNamedPipeBinding(),new EndpointAddress("net.pipe://localhost/test_service_a")); ContractA provider = null; try { provider = pipeFactory.CreateChannel(); provider.DoWork(); } catch { } finally { CloseChannel(provider); //comment the following line to reuse the same ChannelFactory each time try { pipeFactory.Close(); }catch{pipeFactory.Abort();} } } private static void CloseChannel(ContractA provider) { try { if (provider == null) return; try { ((IClientChannel) provider).Close(); } catch { ((IClientChannel) provider).Abort(); } ((IDisposable) provider).Dispose(); } catch (Exception ex) { throw new Exception("Error while closing channel",ex); } } } [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single,ConcurrencyMode = ConcurrencyMode.Multiple)] public class ServiceA : ContractA { //CALLING SERVICE B //uncomment the following line to reuse the same ChannelFactory each time //private readonly ChannelFactory<ContractB> pipeFactory=new ChannelFactory<ContractB>(new NetNamedPipeBinding(),new EndpointAddress("net.pipe://localhost/test_service_b")); public void DoWork() { //comment the following line to reuse the same ChannelFactory each time var pipeFactory=new ChannelFactory<ContractB>(new NetNamedPipeBinding(),new EndpointAddress("net.pipe://localhost/test_service_b")); ContractB provider = null; try { provider = pipeFactory.CreateChannel(); provider.DoWork(); } catch { } finally { CloseChannel(provider); //comment the following line to reuse the same ChannelFactory each time try { pipeFactory.Close(); } catch { pipeFactory.Abort(); } } } private void CloseChannel(ContractB provider) { try { if (provider == null) return; try { ((IClientChannel) provider).Close(); } catch { ((IClientChannel) provider).Abort(); } ((IDisposable) provider).Dispose(); } catch (Exception ex) { throw new Exception("Error while closing channel",ex); } } } [ServiceContract] public interface ContractA { [OperationContract] void DoWork(); } [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single,ConcurrencyMode = ConcurrencyMode.Multiple)] public class ServiceB : ContractB { public void DoWork() { } } [ServiceContract] public interface ContractB { [OperationContract] void DoWork(); } } 解决方法
可能发生的是,您创建的对象比默认工作站垃圾收集器可以摆脱它们更快. .net 3.5 GC的默认延迟模式是交互式的,这意味着如果为了保持UI响应而收集时间过长则会放弃. GC在.net 4& 4.5这可能是你看到不同增长率的原因.
尝试在App.config中打开服务器垃圾回收模式,看看行为是否发生了变化.这应该允许GC工作直到完成. <configuration> <runtime> <gcServer enabled="true"/> </runtime> </configuration> 我假设你使用的是多核系统,否则这将是零影响. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
相关内容
- Application Components(应用的构成)
- map set / get requests into C class / structure changes
- c# – 以“Does”开头的方法名称看起来不错吗?
- ruby – 没有rails的ActiveRecord Schema Dump
- FLEX调用WebService
- 1.2 使用Playground学习Swift [Swift原创教程]
- Libjingle XMPP Login登录返回<failure xmlns="urn:i
- re 模块与正则表达式
- c# – 通用的奇怪行为
- XML基础+Java解析XML +几种解析方式的性能比较