PgSqlDataTable Disposing Failed

Discussion of open issues, suggestions and bugs regarding ADO.NET provider for PostgreSQL
Post Reply
chris901
Posts: 64
Joined: Wed 20 Jul 2016 04:21

PgSqlDataTable Disposing Failed

Post by 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.

Pinturiccio
Devart Team
Posts: 2192
Joined: Wed 02 Nov 2011 09:44

Re: PgSqlDataTable Disposing Failed

Post by 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.

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

Re: PgSqlDataTable Disposing Failed

Post by 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?

Pinturiccio
Devart Team
Posts: 2192
Joined: Wed 02 Nov 2011 09:44

Re: PgSqlDataTable Disposing Failed

Post by 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.

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

Re: PgSqlDataTable Disposing Failed

Post by 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/5555 ... nts-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?

Pinturiccio
Devart Team
Posts: 2192
Joined: Wed 02 Nov 2011 09:44

Re: PgSqlDataTable Disposing Failed

Post by 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)

Post Reply