[英]What System.Drawing classes count as GDI objects?
我一直难以理解System.Drawing
命名空间中哪些确切的对象实际上对系统总 GDI 对象计数有贡献。 例如, Matrix
对象计数吗? GraphicsPath
? Pen
?
为了测试这一点,我在Form
初始化上运行了以下代码。
public partial class Form1 : Form
{
Timer timer = new Timer();
List<Pen> pens = new List<Pen>();
public Form1()
{
InitializeComponent();
var r = new Random();
for (int i = 0; i < 1000; i++)
{
var p = new Pen(
Color.FromArgb(r.Next(255), r.Next(255), r.Next(255)),
(float)r.NextDouble() * 10);
pens.Add(p);
}
timer.Interval = 30;
timer.Tick += timer_Tick;
timer.Start();
}
void timer_Tick(object sender, EventArgs e)
{
panel1.Invalidate();
}
private void panel1_Paint(object sender, PaintEventArgs e)
{
for (int i = 0; i < pens.Count; i++)
{
e.Graphics.DrawLine(pens[i], (int)(20 + i * 0.1), 20, (int)(50 + i * 0.1), 50);
}
}
}
我惊讶地发现我的应用程序 GDI 对象计数为 32(使用任务管理器 > 详细信息 > GDI 对象列测量)。 即使我保留列表并强制Paint
事件使用每个生成的笔绘制单独的线条也是如此。 我什至尝试创建随机颜色以确保没有任何东西被重用,并且 GDI 计数仍然稳定在 32。
有很多帖子担心缓存和重用Pen
实例和其他对象,但我不清楚是否所有System.Drawing
对象都对这个计数有贡献。
也许现代 GDI+ 实现实际上是懒惰的,并且仅在您实际绘制某些东西时才延迟分配?
当您使用 GDI+ 时,您不必像使用 GDI 时那样关心句柄和设备上下文。
似乎 GDI+ 抽象了 GDI 句柄并尽可能避免使用它们。 这也与其他地方的报告一致,这些报告似乎表明 GDI+ 仅在绝对必要时才实际创建 GDI 句柄。 例如,如果您调用需要句柄存在的方法,例如GetHBitmap()
,则Bitmap
仅由句柄支持。
看来,至少在现代 GDI+ 中, Pen
、 Brush
和许多其他System.Drawing
对象实际上并没有对 GDI 对象总数做出贡献。 当然,在 C# 中,如果它们没有被释放,它们仍然会泄漏非托管内存,因为它们由非托管 GDI+ 对象支持,但本机内存不像 GDI 内存那样苛刻。
如果对当前的解释没有异议,我将在接下来的几天内将其移至答案。
以下对象会导致创建 GDI 句柄:
此列表是使用以下信息制定的: https : //docs.microsoft.com/en-gb/windows/desktop/SysInfo/gdi-objects
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.