可能的错误与.NET的WinForms,还是我只是失去了一些东西? GDI对象泄漏 [英] Possible bug with .net winforms, or am I just missing something? GDI object leak

查看:137
本文介绍了可能的错误与.NET的WinForms,还是我只是失去了一些东西? GDI对象泄漏的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

可能有人请告诉我是怎么回事了?

删除吨code找到我们的GDI对象泄漏(使用任务管理器,看GDI对象一栏增加至10,000和我们的应用程序崩溃)后,我减少了code下降到仅.NET code,未安装任何自定义业务code。我们仍然得到的问题。

我创建了一个测试程序来复制这个问题,它具有以下基本行为。

  • 打开一个表格150次(150没什么特别的,只是一个数字足够大,很容易地看到卡手柄)。窗体上的计时器将关闭该窗口 1秒钟后
  • 运行垃圾收集器(不是必须的,但可以帮助摆脱好或工作的对象是不是问题的一部分)
  • 观察应用程序的手动GDI对象计数(你应该之前做到这一点,你打开窗体后,150次)。在我运行测试,我通常得到36计数,测试后,大约190永远一次,我约150运行测试此计数增加。

现在,正在推出的150倍的形式是建立在一种特定的方式(让我们称之为形式的BadForm的是一个静态数据表中绑定到窗体上的组合框。

BadForm有一个组合框就可以了,和一个计时器。这里是code的形式:

 使用系统;
使用System.Data这;
使用System.Drawing中;
使用System.Windows.Forms的;
命名空间GDIObjectLeakTest
{
  公共部分类MyForm的:表
  {
    公共静态数据表CachedNodeType =新的DataTable();

    公共MyForm的()
    {
      的InitializeComponent();
      this.comboBox1.SelectedIndexChanged + =新的EventHandler(this.comboBox1_SelectedIndexChanged);
      this.Font =新的字体(现代20号文,8.249999F,FontStyle.Regular,GraphicsUnit.Point,((字节)(0))); ;
      comboBox1.DataSource = CachedNodeType;
    }

    私人无效timer1_Tick(对象发件人,EventArgs的)
    {
      关闭();
    }

    私人无效comboBox1_SelectedIndexChanged(对象发件人,EventArgs的)
    {}
  }
}
 

下面是$ C $下运行测试应用程序的主要形式。其上有2个按钮。 Button1的运行BadForm 150次。按钮2运行垃圾收集器的100倍(一次或两次不适合我,我猜不够好)(我使用的垃圾收集器只是为了坡口有/是没有问题的)。

 私人无效的button1_Click(对象发件人,EventArgs的)
{
  尝试
  {
    的for(int i = 0; I< 150;我++)
    {
      //新SearchForm()显示()。
      新建MyForm()显示()。
    }
  }赶上(例外EE)
  {
    扔;
  }
}

私人无效button2_Click(对象发件人,EventArgs的)
{
  的for(int i = 0; I< 100;我++)
  {
    所以GC.Collect();
    GC.WaitForPendingFinalizers();
  }
}
 

解决方案

尝试添加到您Dispose方法的顶部(在设计文件中):

  comboBox1.DataSource = NULL;
 

Could someone please tell me what is going wrong?

After removing tons of code to find our GDI object leak (using task manager and watching the "GDI Objects" column grow to 10,000 and our app crashing) I reduced the code down to only .net code without any custom business code. We are still getting the issue.

I created a test app to replicate the issue, which has the following basic behavior.

  • Open the a form 150 times (150 is nothing special, just a number large enough to easily see "stuck" handles). A timer on the form will close the form after 1 second
  • Run the Garbage collector (not really necessary, but can help get rid of the "good" or "working" objects that are not part of the issue)
  • Observe manually the GDI Object count of the app (you should do this before and after you open the form 150 times.) Before I run the test I usually get a count of 36, after the test it is about 190. Ever time I run the test this count increases by about 150.

Now the form that is being launched 150 times is setup in a specific way (Lets call the form "BadForm". The is a static datatable the is bound to a combobox on the form.

BadForm has a comboBox on it, and a timer. Here is the code for the form:

using System;
using System.Data;
using System.Drawing;
using System.Windows.Forms;
namespace GDIObjectLeakTest
{
  public partial class MyForm :Form
  {
    public static DataTable CachedNodeType = new DataTable();

    public MyForm()
    {
      InitializeComponent();
      this.comboBox1.SelectedIndexChanged += new EventHandler(this.comboBox1_SelectedIndexChanged);
      this.Font = new Font("Modern No. 20", 8.249999F, FontStyle.Regular, GraphicsUnit.Point, ((byte)(0))); ;
      comboBox1.DataSource = CachedNodeType;
    }

    private void timer1_Tick(object sender, EventArgs e)
    {
      Close();
    }

    private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
    { }
  }
}   

Here is the code for the main form of the app that runs the test. It has 2 buttons on it. Button1 runs the BadForm 150 times. Button 2 runs the garbage collector 100 times (Once or twice isn't good enough for me I guess) (I'm using the Garbage Collector just to proove there is/isn't a problem).

private void button1_Click(object sender, EventArgs e)
{
  try
  {
    for(int i = 0; i < 150; i++)
    {
      //new SearchForm().Show();
      new MyForm().Show();
    }
  } catch(Exception ee)
  {
    throw;
  }
}

private void button2_Click(object sender, EventArgs e)
{
  for(int i = 0; i < 100; i++)
  {
    GC.Collect();
    GC.WaitForPendingFinalizers();
  }
}

解决方案

Try adding this to the top of your dispose method (in the designer file):

comboBox1.DataSource = null;

这篇关于可能的错误与.NET的WinForms,还是我只是失去了一些东西? GDI对象泄漏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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