本文介绍了如何以及何时处理WinForms控件的字体的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

静态代码分析工具(Fortify from HP)在分配任何控件的Font属性时,抱怨Visual Studio Designer生成的WinForms代码。分析工具会抱怨:

pre $ 143 $ this.mCopyrightLabel.Font = new System.Drawing.Font(Microsoft Sans Serif ,8.25F,System.Drawing.FontStyle.Bold,System.Drawing.GraphicsUnit.Point,((System.Byte)(0)));



我已经搜索了关于在Windows窗体中处理字体一段时间的主题,这些是我收集的几点:$ b​​
$ b


  1. 创建字体将占用一个GDI对象,这是一个非托管资源,因此重要的是在不再需要时被释放

  2. GDI对象是昂贵且稀缺的,WinForm缓存它们。


  3. 处理WinForms控件也会处理所有的子控件,并释放获得的非托管资源。 modeless

因此,我想得出结论:在VS生成的代码中不需要显式地分配给控件的Font,不应该这样做,因为字体缓存?

我创建了一个非常简单的表单测试程序:通过单击一个按钮,我创建一个新的空表单谁使用不同的字体。关闭新打开的窗体后,任务管理器中的GDI对象计数立即下降。这是上面提到的几点的证据,不是吗?

但是静态分析器似乎并不相信。它相信字体将最终由GC发布。它也认为这对于非托管资源并不好,因为消耗的内存不在GC的知识范围之内,因此GC不会及时触发GC,因为GC没有内存压力。这给了攻击者一个机会来故意触发耗尽非托管池。

你能帮我理解一下分析器给出的解释吗?它是有效的WinFroms?手动处理每个创建的字体将是一件繁琐的工作。



确切地说:

在Dispose of a Control或Control中释放对Font的引用,并让GC处理所有剩下的内容?

谢谢!

进一步更新我的问题:
我做的另一个实验是:我在TaskManager和内存分析器中监视了我的测试WinForm应用程序。主窗体有一个按钮,将打开另一个窗体的字体是不同的,当点击。我注意到,当我点击按钮并打开新的窗体时,TaskManager中的GDI对象数量上升。作为内存分析器观察到的字体对象的计数。然而,当我关闭新的Form时,TaskManager中的GDI对象的计数立即下降了。内存分析器中的字体对象的计数没有改变,暗示GC没有发生。但是,这些Font对象在内存分析器中被标记为已处理但未收集。

这让我感觉Font对象设置为WinForms控件的字体属性已被妥善处理,当窗体关闭。看来这个场景背后的逻辑是:


  1. WinForm在关闭的时候处理一个Form(显式地,不是由GC) b $ b
  2. 处理表单将递归地处置其所有子控件
  3. 处理控件将处理与其Font属性关联的Font对象(同样,显式地,而不是GC) / li>

但这只是间接证明+我的分析。我没有任何直接的证据,如源代码或官方文件来支持它。

解决方案

当Form被关闭时,GC将自动处理,不需要显式地处理字体

A static code analysis tool (Fortify from HP) is complaining about Visual Studio Designer generated WinForms code when Font property of any control is assigned. The analysis tool complains :

line 143: this.mCopyrightLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));

I have been searched the topic regarding the disposing of font in windows forms for a while, and these are the points I gathered:

  1. creating font will occupy a GDI object, which is an unmanaged resource and therefore is important to be released when no longer needed
  2. Since GDI objects are expensive and scarce, WinForm caches them.
  3. Dispose WinForms control will also dispose all its child control and "release the unmanaged resource obtained"
  4. Form will be disposed when closed if the Form is modeless

Therefore I want to conclude that there is no need to explicit dispose Font assigned to controls in VS-generated code, and probably we should not to do so since fonts are cached?

I created a very simple Form test program: by clicking a button I create a new empty form who uses a different font. The GDI object count in Task Manager goes down immediately after I close the newly opened Form. This is an evidence of the above mentioned points, isn't it?

However the static analyzer seems not to believe the same. It believes the Font will eventually be released by GC. It also believes this is not good for unmanaged resource since the memory consumed sits outside GC's knowledge therefore GC will not be triggered timely because GC feels no memory pressure. This give attacker an opportunity to intentionally trigger deplete the unmanaged pool.

Can you help me a little on understanding the explanation given by the analyzer? Is it valid for WinFroms ? It would be tedious to manually dispose every Font created.

To be precise:

Is Font disposed immediately and explicitly during the Dispose of a Control, or Control release the reference to the Font and let GC handle all the left?

Thanks!

A further update to my question:Another experiment I did is: I monitored my test WinForm application in both TaskManager and a memory profiler. The main Form has a button which will open another Form whose Font is different when clicked. I noticed that when I clicked the button and opened the new Form, the GDI object count in TaskManager goes up. So as the count of Font objects observed by memory profiler.

However, when I closed the new Form, the count of GDI objects in TaskManager went down immediately. The count of Font objects in the memory profiler did not change, implying the GC did not happen. These Font objects, however, were tagged as "disposed but not collected" in the memory profiler.

It gives me this feeling that Font object set to WinForms Control's Font property has been properly disposed when Form is closed. It seems the logic behind the scene is

  1. WinForm disposes a Form when it is closed (explicitly, not by GC)
  2. Dispose a Form will recursively dispose all its child Controls
  3. Dispose a Control will dispose the Font object associated with its Font property (again, explicitly, not by GC)

But this is just indirect proof + my analysis. I dont have any direct proof like source code or official document to support it.

解决方案

When Form is closed , GC will dispose automatically no need to explicitly dispose font

这篇关于如何以及何时处理WinForms控件的字体的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-05 13:36
查看更多