如何以及何时处理WinForms控件的字体 [英] How and when is Font disposed for WinForms controls

查看:227
本文介绍了如何以及何时处理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)));




AboutWindowForm.cs中的InitializeComponent()函数无法正确处理



解释:

程序无法正确处置使用非托管系统资源的托管对象的一部分。
如果未正确处置使用非托管系统资源的托管对象,至少有两个原因:


  • 错误情况和其他例外的情况。
  • 混淆程序的哪一部分负责释放资源。


    在这种情况下,程序路径上的143行的AboutWindowForm.cs中分配的资源没有正确处理。



    受管.NET对象的一小部分使用非托管系统资源。 .NET的垃圾收集器不能以可预测的方式释放原始的管理对象。因此,应用程序可能会用尽可用内存,因为垃圾收集器不知道非托管资源消耗的内存。大多数非托管资源泄漏问题会导致一般的软件可靠性问题,但是如果攻击者可以有意识地触发非托管资源泄漏,则攻击者可能会通过耗尽非托管资源池来启动拒绝服务攻击。

我已经搜索了关于在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)));

The function InitializeComponent() in AboutWindowForm.cs fails to properly dispose of unmanaged system resources allocated by Font() on line 143.

Explanation:

The program fails to properly dispose of a managed object that uses unmanaged system resources. Failure to properly dispose of a managed object that uses unmanaged system resources has at least two common causes:

  • Error conditions and other exceptional circumstances.
  • Confusion over which part of the program is responsible for releasing the resource.

In this case, there are program paths on which the resource allocated in AboutWindowForm.cs at line 143 is not disposed of properly.

A small subset of managed .NET objects use unmanaged system resources. .NET's Garbage Collector may not free the original managed objects in a predictable way. As such, the application may run out of available memory as the Garbage Collector is unaware of the memory consumed by the unmanaged resources. Most unmanaged resource leak issues result in general software reliability problems, but if an attacker can intentionally trigger an unmanaged resource leak, the attacker might be able to launch a denial of service attack by depleting the unmanaged resource pool.

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控件的字体的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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