什么是C#winform应用程序中的UserPreferenceChangedEventHandler? [英] What is UserPreferenceChangedEventHandler in C# winform applications?

查看:160
本文介绍了什么是C#winform应用程序中的UserPreferenceChangedEventHandler?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我发现某些Winform应用程序控件(例如DataGridView和ToolStrips)由UserPreferenceChangedEventHandlers引用。我不知道控件的哪种设置将生成此类引用,以及为什么此类引用会使我的控件在内存中保持活动状态。如何从该事件中删除此类引用?谢谢。

I found some of my winform application controls, such as DataGridView and ToolStrips, are referred to by UserPreferenceChangedEventHandlers. I have no idea what setting of the controls will generate such references and why such references keep my control alive in memory. How can I remove such references from that event? Thanks.

推荐答案

它是SystemEvents.UserPreferenceChanged事件的委托类型。 Windows广播WM_SETTINGCHANGE消息时,将触发此事件。当用户使用控制面板小程序并更改系统设置时,通常会发生这种情况。

It is the delegate type for the SystemEvents.UserPreferenceChanged event. This event fires when Windows broadcasts the WM_SETTINGCHANGE message. Which typically happens when the user uses a control panel applet and changes a system setting.

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

Several controls register an event handler for this event, DataGridView, DateTimePicker, MonthCalendar, ProgressBar, PropertyGrid, RichTextBox, ToolStrip, NumericUpDown. They typically are interested in font or cue changes and anything that would affect the layout.

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

SystemEvents.UserPreferenceChanged is a static event. Registering a handler and forgetting to unregister it causes a memory leak, it prevents the control from being garbage collected. The listed controls ensure this doesn't happen, they unregister the event handler in either the OnHandleDestroyed() or the Dispose() method.

当这两种方法均未运行。当您从容器的Controls集合中删除控件而忘记了Dispose()时,就会发生这种情况。尽管忘记调用Dispose()通常不是问题,但这是控件的硬性要求。也很容易忘记,控件通常由表单自动处理。

You'll get in trouble when neither of those two methods run. That will happen when you remove the control from the container's Controls collection and forget to Dispose() it. While forgetting to call Dispose() is not normally a problem, it is a hard requirement for controls. It is easy to forget too, controls are normally automatically disposed by the Form. But that only happens for controls in the Controls collection.

另外,请务必在获取ShowDialog()方法显示的表单上调用Dispose()。对话结果。使用语句是处理该问题的最佳方法。

Also be sure to call Dispose() on forms that you display with the ShowDialog() method, after you obtained the dialog results. The using statement is the best way to handle that.

关于UserPreferenceChanged事件,还有一个令人费解的细节很重要,它是通常是在工作线程上创建控件时使应用死锁的代码。通常,当工作站被锁定时(按Win + L)。当您使用我列出的控件时,效果不好,SystemEvents类尝试在UI线程上引发事件,但是当多个线程创建了UIEvent时,当然不能正确执行此操作。

One more excruciating detail is important about the UserPreferenceChanged event, it is often the one that deadlocks your app when you create controls on a worker thread. Typically when the workstation is locked (press Win+L). Which cannot come to a good end when you use the controls I listed, the SystemEvents class tries to raise the event on the UI thread but of course cannot do this correctly when more than one thread has created them.

另外,这种错误可能会产生持久的影响,例如启动屏幕可以使SystemEvents类猜测关于UI线程的错误。之后,它将在错误的线程上永久引发该事件。 进行诊断,死锁被很好地隐藏了。

Also the kind of bug that can have a lasting effect, a splash screen for example can get the SystemEvents class to guess wrong about which thread is your UI thread. After which it then permanently raises the event on the wrong thread. Very ugly to diagnose, the deadlock is well hidden.

这篇关于什么是C#winform应用程序中的UserPreferenceChangedEventHandler?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆