本地范围内具有事件处理程序的GDI对象

问题描述 投票:0回答:1

我有一个简短的问题,我一直无法在其他地方找到答案。

我们有一个大型的4.0桌面应用程序(想想3个解决方案中的大约100个项目),它们遇到了10k + GDI对象问题。显然我们在某个地方有泄漏。我最近一直在做很多测试,以确切地知道可能是什么问题。其中一些是.NET,例如,一个TabControl的每个新实例,即使是处置,似乎留下一个GDI对象(每个打开/关闭的形式从79个对象增加到80个,然后是81个,然后是82个,等等。)但显然我们的用户不是每天打开带有标签控件的表单10,000次。

在我的问题上:我是否必须为本地范围代码发布事件处理程序,如下所示:

            UserLoginManager loginManager = new UserLoginManager();
            loginManager.LoginFailed += HandleFailedLogin;
            loginManager.LoginSuccessful += HandleSuccessfulLogin;

            loginManager.LogUserInAsync(this.UserNameTextBox.Text.Trim(), this.PasswordTextBox.Text.Trim());

我问这个是因为如果事件处理程序分配给一个在应用程序生命周期内保持打开的表单,我不确定该对象是否会正确GC。

c# multithreading gdi
1个回答
0
投票

GC仅在一个方向上追踪参考。您注册的事件处理程序委托将具有对表单的引用(如果它们是实例方法),并且事件本身保存对委托的引用。但如果没有任何东西持有对UserLoginManager的引用,那么它将有资格收集,并且它(传递)持有的引用将不会保持其他对象存活。

事件处理程序和泄漏的风险是相反的 - 如果你有一个暴露事件的长期存在的对象,并且你有想要短命的对象 - 如果那些“应该是短暂的”对象注册事件处理程序和以后不能注销它们会延长它们的寿命。

© www.soinside.com 2019 - 2024. All rights reserved.