繁体   English   中英

哪些 System.Drawing 类算作 GDI 对象?

[英]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+ 实现实际上是懒惰的,并且仅在您实际绘制某些东西时才延迟分配?

更新: GSerg指出MSDN 官方文档

当您使用 GDI+ 时,您不必像使用 GDI 时那样关心句柄和设备上下文。

似乎 GDI+ 抽象了 GDI 句柄并尽可能避免使用它们。 这也与其他地方的报告一致,这些报告似乎表明 GDI+ 仅在绝对必要时才实际创建 GDI 句柄。 例如,如果您调用需要句柄存在的方法,例如GetHBitmap() ,则Bitmap仅由句柄支持。

看来,至少在现代 GDI+ 中, PenBrush和许多其他System.Drawing对象实际上并没有对 GDI 对象总数做出贡献。 当然,在 C# 中,如果它们没有被释放,它们仍然会泄漏非托管内存,因为它们由非托管 GDI+ 对象支持,但本机内存不像 GDI 内存那样苛刻。

如果对当前的解释没有异议,我将在接下来的几天内将其移至答案。

以下对象会导致创建 GDI 句柄:

  • 位图
  • 直流电
  • 增强型图元文件
  • 增强型元文件 DC
  • 字体
  • 内存直流
  • 元文件
  • 图元文件 DC
  • 调色板
  • 钢笔
  • 加长笔
  • 地区

此列表是使用以下信息制定的: https : //docs.microsoft.com/en-gb/windows/desktop/SysInfo/gdi-objects

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM