Winforms C#winform应用程序中的UserPreferenceChangedEventHandler是什么?

Winforms C#winform应用程序中的UserPreferenceChangedEventHandler是什么?,winforms,c#-3.0,Winforms,C# 3.0,我发现我的一些winform应用程序控件,如DataGridView和ToolStrips,是由UserPreferenceChangedEventHandler引用的。我不知道控件的什么设置会生成这样的引用,也不知道为什么这样的引用会使我的控件在内存中保持活动状态。如何从该事件中删除此类引用?谢谢。这是SystemEvents.UserPreferenceChanged事件的委托类型。Windows广播WM_SETTINGCHANGE消息时激发此事件。这通常发生在用户使用控制面板小程序并更改系

我发现我的一些winform应用程序控件,如DataGridView和ToolStrips,是由UserPreferenceChangedEventHandler引用的。我不知道控件的什么设置会生成这样的引用,也不知道为什么这样的引用会使我的控件在内存中保持活动状态。如何从该事件中删除此类引用?谢谢。

这是SystemEvents.UserPreferenceChanged事件的委托类型。Windows广播WM_SETTINGCHANGE消息时激发此事件。这通常发生在用户使用控制面板小程序并更改系统设置时

有几个控件为此事件注册事件处理程序DataGridView、DateTimePicker、MonthCalendar、ProgressBar、PropertyGrid、RichTextBox、ToolStrip、NumericUpDown。他们通常对字体或提示的更改以及任何可能影响布局的内容感兴趣

SystemEvents.UserPreferenceChanged是一个静态事件。注册处理程序而忘记取消注册会导致内存泄漏,从而防止控件被垃圾收集。列出的控件确保不会发生这种情况,它们在OnHandleDestroyed()或Dispose()方法中注销事件处理程序

如果这两种方法都不运行,您将遇到麻烦。当您从容器的Controls集合中删除控件并忘记处置()它时,就会发生这种情况。虽然忘记调用Dispose()通常不是问题,但对于控件来说,这是一个困难的要求。也很容易忘记,控件通常由窗体自动处理。但这仅适用于控件集合中的控件

另外,确保在获得对话框结果后,对使用ShowDialog()方法显示的表单调用Dispose()。using语句是处理这个问题的最佳方法


关于UserPreferenceChanged事件,还有一个非常重要的细节,当你在工作线程上创建控件时,它通常会使你的应用程序死锁。通常在工作站锁定时(按Win+L)。当您使用我列出的控件时,SystemEvents类会尝试在UI线程上引发事件,但当多个线程创建了这些事件时,当然无法正确地引发事件


还有一种可能产生持久影响的bug,例如启动屏幕可能会让SystemEvents类猜错哪个线程是您的UI线程。之后,它会在错误的线程上永久引发事件。非常难看,僵局隐藏得很好。

谢谢你的建议。我检查了代码,似乎有问题的控件被添加到了一个面板的控件列表中,该面板被添加到了另一个面板的控件列表中,最后根面板被添加到表单的控件列表中。从内存分析器中,我还可以看到控件的dispose方法被调用,但是UserPreferenceChangedEventHandler仍然挂起。这是我不明白的部分。还有什么我没有注意到的吗?回答很好,但正如Steve提到的,有时候即使你处理了控制,你仍然有这个问题。有几个关于此问题的连接条目,例如:。