PgSqlDataTable Disposing Failed

PgSqlDataTable Disposing Failed

Postby chris901 » Sun 21 Aug 2016 08:38

Hello,

i have 2 Forms (Form1 and Form2).

In Form1 i create a new Form2 with a click on a button and dispose that form with another button:

Code: Select all
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private Form _form;

        private void button1_Click(object sender, EventArgs e)
        {
            _form = new Form2();
            _form.Show();
        }

        private void button2_Click(object sender, EventArgs e)
        {
            _form.Dispose();
        }
    }




Form2 has an Timer and PgSqlDataTable component placed on it: Image

Form 2 also introduces the disposing events for both the Timer and the SqlDataTable:

Code: Select all
    public partial class Form2 : Form
    {
        public Form2()
        {
            InitializeComponent();
        }

        private void Form2_Load(object sender, EventArgs e)
        {
            timer1.Disposed += delegate { MessageBox.Show("timer1 - Disposed"); };
            pgSqlDataTable1.Disposed += delegate { MessageBox.Show("pgSqlDataTable1 - Disposed"); };
        }
    }


However when i dispose the Form2 in Form1 (button2_Click) only the Timer gets disposed and the message shown.

Could it be that SqlDataTable doesn't get disposed correctly?!

Thanks.
chris901
 
Posts: 64
Joined: Wed 20 Jul 2016 04:21

Re: PgSqlDataTable Disposing Failed

Postby Pinturiccio » Thu 25 Aug 2016 10:10

We have reproduced the issue. We will investigate it and post here about the results as soon as possible.
Pinturiccio
Devart Team
 
Posts: 1979
Joined: Wed 02 Nov 2011 09:44

Re: PgSqlDataTable Disposing Failed

Postby chris901 » Mon 29 Aug 2016 17:53

Thanks for fixing this. Can't wait to get rid of that memory leak. Got any timeframe about the hotfix?
chris901
 
Posts: 64
Joined: Wed 20 Jul 2016 04:21

Re: PgSqlDataTable Disposing Failed

Postby Pinturiccio » Tue 30 Aug 2016 14:37

When the Dispose method is called for a form, the following code is executed:
Code: Select all
protected override void Dispose(bool disposing) {
   if (disposing && (components != null)) {
      components.Dispose();
   }
   base.Dispose(disposing);
}


When a Timer object is created, it is added to the components container. So, when a Form is disposed, the Dispose method is called for all objects in the components container, including the Timer object.

When the PgSqlDataTable object is added to a Form, the PgSqlDataTable object is not added to the components container. So, when the Form with the PgSqlDataTable object is disposed, the Dispose method is not called for PgSqlDataTable. It is a designed behavior; the same behavior can be noticed in the Microsoft DataSet component as well, for example. You should call the Dispose method of PgSqlDataTable yourself.
Pinturiccio
Devart Team
 
Posts: 1979
Joined: Wed 02 Nov 2011 09:44

Re: PgSqlDataTable Disposing Failed

Postby chris901 » Wed 31 Aug 2016 02:52

I see.

I've also looked it up on SO and found this interesting question:
http://stackoverflow.com/questions/555526/why-does-the-visual-studio-ide-sometimes-initialize-the-this-components-object

So it really seems to be the best way to dispose it manually because you can't always rely on the designer.

I've also found on SO a way to iterate through all components:

Code: Select all
http://stackoverflow.com/questions/38310117/delphi-to-c-sharp-winforms-iterate-through-form-components-on-form

private IEnumerable<Component> EnumerateComponents()
{
            return from field in GetType().GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
                   where typeof(Component).IsAssignableFrom(field.FieldType)
                   let component = (Component)field.GetValue(this)
                   where component != null
                   select component;
}

However my problem is that PgSqlDataTable never gets listed there?
Timer, PgSqlConnection, PgSqlCommand, PgSqlDataAdapter and all the other components get listed there and I can dispose them in e.g. the form desctructor.

Do you have an idea why PgSqlDataTable doesn't appear in the result of EnumerateComponents() listed there? Isn't it a descendant of IComponent or some other issue?
chris901
 
Posts: 64
Joined: Wed 20 Jul 2016 04:21

Re: PgSqlDataTable Disposing Failed

Postby Pinturiccio » Mon 05 Sep 2016 15:57

chris901 wrote:Do you have an idea why PgSqlDataTable doesn't appear in the result of EnumerateComponents() listed there?

The reason is that PgSqlConnection, PgSqlCommand, PgSqlDataAdapter classes are descendants of the Component class, and PgSqlDataTable class is not. PgSqlDataTable class is inherited from System.Data.Table class, which is not inherited from the Component class.

Thus, PgSqlDataTable does not meet the condition: typeof(Component)
Pinturiccio
Devart Team
 
Posts: 1979
Joined: Wed 02 Nov 2011 09:44


Return to dotConnect for PostgreSQL