此 WCF 客户端代码会导致内存泄漏吗?
.Net 中内存泄漏的常见原因之一是事件处理程序从未从其源对象中删除。
此 WCF 代码是否会导致内存泄漏,或者 lambda 是否也会超出范围,从而允许代理类和处理程序被 GC ?
void AMethod()
{
WCFClient proxy;
proxy = new WCFClient();
proxy.RemoteOperationCompleted += (sender, e) => proxy.Close();
proxy.Open();
proxy.RemoteOperationAsync();
}
One of the frequent causes of memory leaks in .Net are event handlers which are never removed from their source objects.
Will this WCF code cause a memory leak, or will the lambda go out of scope too, allowing both the proxy class and the handler to be GCed?
void AMethod()
{
WCFClient proxy;
proxy = new WCFClient();
proxy.RemoteOperationCompleted += (sender, e) => proxy.Close();
proxy.Open();
proxy.RemoteOperationAsync();
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
这是我的测试 - 请注意 lambda 中的显式
proxy
设置为null
- 如果没有它,WeakReference
就会存在,因此可能会发生泄漏:Here's my test - note the explicit
proxy
set tonull
in the lambda - without it theWeakReference
lives and therefore a leak is likely:不要忘记代理没有正确实现 IDisposable。 如果发生错误,上面的代码将不会清理连接,并且句柄将保留到父进程关闭为止。
Don't forget that the proxy's don't correctly implement IDisposable. If an error occurs the code above will not clean up the connection and the handle will remain until the parent process is closed.
定义 lamdba 的上下文将被捕获,因此将在编译器创建的闭包类中“生存”(您可以使用 Reflector 看到它们) - 所以您的代理也是如此。 使用弱事件处理程序或编写注销代码。 但在这种情况下你不能使用 lambda 表达式。
The context where the lamdba is defined will be captured and will therefore "survive" in the compiler created closure class (you can see them with Reflector) - so your proxy too. Use weak event handler or write code for unregistration. But in that case you can't use lambda expression.
那个物体会死……它会被清理掉。
不要忘记 lamda 没有做任何特殊的事情......这是一个编译器技巧(所以假设它是一个正常的 += SomeDelegate)。
另外,“Close”方法(我不知道为什么他们没有将其设为 IDisposable)将清除所有其他打开的内容。
That object will die... it'll be cleaned up.
Don't forget that the lamda isn't doing anything special... it's a compiler trick (so just assume it's a normal += SomeDelegate).
Also, the "Close" method (I don't know why they didn't make it IDisposable) will clean up everything else that was left open.