Solved

Why a windows form is not disposed ?

Posted on 2008-06-23
5
793 Views
Last Modified: 2013-11-07
I have a VB NET application.

In a form I am building some charts, using XTRACHARTS library.

All objects inside of that form, was declared PRIVATE.

When I close the form, I need to guarantee that the form IS DISPOSED, in order to release all memory used by it.

Please see the following:

XtraCharts.ShowDialog()
XtraCharts.Dispose()
GC.Collect()
Dim Mem As Process
Mem = Process.GetCurrentProcess()
SetProcessWorkingSetSize(Mem.Handle, -1, -1)
If XtraCharts.IsDisposed Then
   msgbox("The form is not disposed")
End If

XtraCharts.IsDisposed ALLWAYS RETURN FALSE, and memory (a lot memory) used by the charts objects was not released..!!

When I execute:

Dim Mem As Process
Mem = Process.GetCurrentProcess()
SetProcessWorkingSetSize(Mem.Handle, -1, -1)

Ok, the amount of free RAM is increased, because all possible pages in RAM was moved to the page file on the hard disk.

But, when I return to the XtraCharts.ShowDialog(), the performance is very slow, because all pages needed by the XtraCharts objects are moved back from the page file on hard disk to the RAM.

These I/O operations "FREEZE" the application for a long time...!!!.

I made another test:

TestFormWithoutCode.ShowDialog() '----- this form have not any code
TestFormWithoutCode.dispose()
GC.Collect()

If TestFormWithoutCode.IsDisposed Then
   msgbox("The form is not disposed")
End If

TestFormWithoutCode.IsDisposed    ALLWAYS RETURN FALSE TOO..!!

What are happening?

How I can do to REALLY DISPOSE a form?

In my case, I believe that the SetProcessWorkingSetSize(Mem.Handle, -1, -1), is not a good solution (I was found a lot information about it).

I need to find a way to REALLY RELEASE that objects ..!!!!, and the next time I need it, simply create it again, all in memory, of course. I dont want swap to the hard disk that objects...!!!

In my case, I believe that I have 2 options:

1)  Found a way to REALLY CLOSE, DISPOSE, AND REALEASE all objects and resources included inside of XtraCharts form.

2)  Create another VB project XtraCharts, and execute it using Process.Start("XtraCharts.exe")
(Obviously, I will need to pass the source data to build the charts..!! using some xml file, because I  have the source data stored in a grid in the main application).

3) There is a way to RUN the XtraCharts.form in a separate process from the main application and ensure that when it exits, all resources will be released?

I will appreciate any USEFULL COMENTS.
0
Comment
Question by:luiggye
  • 3
  • 2
5 Comments
 
LVL 25

Expert Comment

by:apeter
Comment Utility
Even though the instance of a control is disposed of, it is still maintained in memory until it is removed from memory through garbage collection.

when you call GC.Collect(0, all objects, regardless of how long they have been in memory, are considered for collection; however, objects that are referenced in managed code are not collected.

You have to do a "Load test"  to see whether your chart objects are not getting cleared. Also you can do for the same logic for some other resource object and see the behaviour.
0
 

Author Comment

by:luiggye
Comment Utility
Thanks Apeter for your comments.

I was made some test and I can tell you the following:

I have 35 forms in my application.

I always am using:

FormXX.showdialog()
FormXX.dispose()
if not FormXX.isDisposed then
   msgbox("Form is not disposed")
endif

Some times, a form is successfully disposed, others not.

Inspecting the source code, I found the following code, only for some forms, not for all form, in the .designer.vb files.

    Inherits System.Windows.Forms.Form

    'Form overrides dispose to clean up the component list.
    <System.Diagnostics.DebuggerNonUserCode()> _
    Protected Overrides Sub Dispose(ByVal disposing As Boolean)
        Try
            If disposing AndAlso components IsNot Nothing Then
                components.Dispose()
            End If
        Finally
            MyBase.Dispose(disposing)
        End Try
    End Sub

That code was generated by the Windows Form Designer, but I don't know why was generated for some forms and others not..!!!

Do you know why?

Anyway, that code, not have relation about the dispose success or fail.

Thanks again.



This is a example of a form definition
 

<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _

Partial Class frmConditionalFormat

    Inherits System.Windows.Forms.Form
 

    'Form overrides dispose to clean up the component list.

    <System.Diagnostics.DebuggerNonUserCode()> _

    Protected Overrides Sub Dispose(ByVal disposing As Boolean)

        Try

            If disposing AndAlso components IsNot Nothing Then

                components.Dispose()

            End If

        Finally

            MyBase.Dispose(disposing)

        End Try

    End Sub
 

    'Required by the Windows Form Designer

    Private components As System.ComponentModel.IContainer
 

    'NOTE: The following procedure is required by the Windows Form Designer

    'It can be modified using the Windows Form Designer.  

    'Do not modify it using the code editor.

    <System.Diagnostics.DebuggerStepThrough()> _

    Private Sub InitializeComponent()

        Me.cmbOperators = New System.Windows.Forms.ComboBox

        Me.txtValue1 = New System.Windows.Forms.TextBox

        Me.txtValue2 = New System.Windows.Forms.TextBox

        Me.btnExit = New System.Windows.Forms.Button

        Me.btnFontsColors = New System.Windows.Forms.Button

        Me.fraFormatConditions = New System.Windows.Forms.GroupBox

        Me.lblValue2 = New System.Windows.Forms.Label

        Me.lblValue1 = New System.Windows.Forms.Label

        Me.lblOperators = New System.Windows.Forms.Label

        Me.btnAply = New System.Windows.Forms.Button

        Me.fraFormatConditions.SuspendLayout()

        Me.SuspendLayout()

        '

        'cmbOperators

        '

        Me.cmbOperators.FormattingEnabled = True

        Me.cmbOperators.Location = New System.Drawing.Point(20, 43)

        Me.cmbOperators.Name = "cmbOperators"

        Me.cmbOperators.Size = New System.Drawing.Size(97, 21)

        Me.cmbOperators.TabIndex = 0

        '

        'txtValue1

        '

        Me.txtValue1.Location = New System.Drawing.Point(141, 44)

        Me.txtValue1.Name = "txtValue1"

        Me.txtValue1.Size = New System.Drawing.Size(126, 20)

        Me.txtValue1.TabIndex = 1

        '

        'txtValue2

        '

        Me.txtValue2.Location = New System.Drawing.Point(141, 85)

        Me.txtValue2.Name = "txtValue2"

        Me.txtValue2.Size = New System.Drawing.Size(126, 20)

        Me.txtValue2.TabIndex = 2

        Me.txtValue2.Visible = False

        '

        'btnExit

        '

        Me.btnExit.DialogResult = System.Windows.Forms.DialogResult.Cancel

        Me.btnExit.Location = New System.Drawing.Point(314, 95)

        Me.btnExit.Name = "btnExit"

        Me.btnExit.Size = New System.Drawing.Size(93, 28)

        Me.btnExit.TabIndex = 3

        Me.btnExit.Text = "Exit"

        Me.btnExit.UseVisualStyleBackColor = True

        '

        'btnFontsColors

        '

        Me.btnFontsColors.Location = New System.Drawing.Point(315, 64)

        Me.btnFontsColors.Name = "btnFontsColors"

        Me.btnFontsColors.Size = New System.Drawing.Size(93, 28)

        Me.btnFontsColors.TabIndex = 4

        Me.btnFontsColors.Text = "Fonts/Colors"

        Me.btnFontsColors.UseVisualStyleBackColor = True

        '

        'fraFormatConditions

        '

        Me.fraFormatConditions.Controls.Add(Me.lblValue2)

        Me.fraFormatConditions.Controls.Add(Me.lblValue1)

        Me.fraFormatConditions.Controls.Add(Me.lblOperators)

        Me.fraFormatConditions.Controls.Add(Me.cmbOperators)

        Me.fraFormatConditions.Controls.Add(Me.txtValue1)

        Me.fraFormatConditions.Controls.Add(Me.txtValue2)

        Me.fraFormatConditions.Location = New System.Drawing.Point(16, 18)

        Me.fraFormatConditions.Name = "fraFormatConditions"

        Me.fraFormatConditions.Size = New System.Drawing.Size(284, 125)

        Me.fraFormatConditions.TabIndex = 7

        Me.fraFormatConditions.TabStop = False

        Me.fraFormatConditions.Text = "Format Conditions"

        '

        'lblValue2

        '

        Me.lblValue2.AutoSize = True

        Me.lblValue2.Location = New System.Drawing.Point(138, 69)

        Me.lblValue2.Name = "lblValue2"

        Me.lblValue2.Size = New System.Drawing.Size(34, 13)

        Me.lblValue2.TabIndex = 5

        Me.lblValue2.Text = "Value"

        Me.lblValue2.Visible = False

        '

        'lblValue1

        '

        Me.lblValue1.AutoSize = True

        Me.lblValue1.Location = New System.Drawing.Point(138, 24)

        Me.lblValue1.Name = "lblValue1"

        Me.lblValue1.Size = New System.Drawing.Size(34, 13)

        Me.lblValue1.TabIndex = 4

        Me.lblValue1.Text = "Value"

        '

        'lblOperators

        '

        Me.lblOperators.AutoSize = True

        Me.lblOperators.Location = New System.Drawing.Point(17, 24)

        Me.lblOperators.Name = "lblOperators"

        Me.lblOperators.Size = New System.Drawing.Size(53, 13)

        Me.lblOperators.TabIndex = 3

        Me.lblOperators.Text = "Operators"

        '

        'btnAply

        '

        Me.btnAply.Location = New System.Drawing.Point(314, 32)

        Me.btnAply.Name = "btnAply"

        Me.btnAply.Size = New System.Drawing.Size(93, 28)

        Me.btnAply.TabIndex = 8

        Me.btnAply.Text = "Aply"

        Me.btnAply.UseVisualStyleBackColor = True

        '

        'frmConditionalFormat

        '

        Me.AcceptButton = Me.btnAply

        Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)

        Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font

        Me.ClientSize = New System.Drawing.Size(419, 162)

        Me.ControlBox = False

        Me.Controls.Add(Me.btnAply)

        Me.Controls.Add(Me.fraFormatConditions)

        Me.Controls.Add(Me.btnExit)

        Me.Controls.Add(Me.btnFontsColors)

        Me.Name = "frmConditionalFormat"

        Me.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide

        Me.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent

        Me.Text = "Format Conditions Assistant"

        Me.fraFormatConditions.ResumeLayout(False)

        Me.fraFormatConditions.PerformLayout()

        Me.ResumeLayout(False)
 

    End Sub

    Friend WithEvents cmbOperators As System.Windows.Forms.ComboBox

    Friend WithEvents txtValue1 As System.Windows.Forms.TextBox

    Friend WithEvents txtValue2 As System.Windows.Forms.TextBox

    Friend WithEvents btnExit As System.Windows.Forms.Button

    Friend WithEvents btnFontsColors As System.Windows.Forms.Button

    Friend WithEvents fraFormatConditions As System.Windows.Forms.GroupBox

    Friend WithEvents lblValue1 As System.Windows.Forms.Label

    Friend WithEvents lblOperators As System.Windows.Forms.Label

    Friend WithEvents lblValue2 As System.Windows.Forms.Label

    Friend WithEvents btnAply As System.Windows.Forms.Button

End Class

Open in new window

0
 
LVL 25

Expert Comment

by:apeter
Comment Utility
Looks like those set of forms are using some 3rd party or custom componenets. So they have override the dispose method of the form to release the memory of the component. This is the right way to do but the logic should be changed in a standard way like below. And this is not autogenerated code i guess.

Hope after calling your dispose method, your using "GC.SuppressFinalize(Me)" and it should look like below.

Public Overloads Sub Dispose() Implements IDisposable.Dispose
            Dispose(True)
            GC.SuppressFinalize(Me)
        End Sub
        Protected Overrides Sub Finalize()
            Dispose(False)
            MyBase.Finalize()
        End Sub

And your Dispose method should like below.
Protected Overridable Overloads Sub Dispose( _
            ByVal disposing As Boolean)
                If disposing Then
                    components.Dispose()
                End
        End Sub


0
 

Accepted Solution

by:
luiggye earned 0 total points
Comment Utility
Thanks for your response Apeter.

I was resolved my problem, creating another project, only for charts, and calling it using Process.Start (AppCharts), and when the AppCharts.exe ends, all resources are automatically released.

But I am very interesting in your suggestion, in order to ensure that when a close a form, all resources will be released.

I understood your comments, but I dont know where I must to include that code.

I could to include it in every form? Where?

Can you send me a detailed example, pls? (Mybe a litle but complete solution example).

Thanks in advance,
0
 
LVL 25

Expert Comment

by:apeter
Comment Utility
Below i have picked up some definiions from MSDN and hope it gives more clear idea. Sorry for not putting it as code.

Dipose(bool Diposing) disposes of the resources (other than memory) used by the Form. true to release both managed and unmanaged resources; false to release only unmanaged resources.

This method is called by the public Dispose method and the Finalize method. Dispose invokes the protected Dispose(Boolean) method with the disposing parameter set to true. Finalize invokes Dispose with disposing set to false.

When the disposing parameter is true, this method releases all resources held by any managed objects that this Form references, in your case the Charts objects.

Dispose will be called automatically if the form is shown using the Show method. If another method such as ShowDialog is used, or the form is never shown at all, you must call Dispose yourself within your application.

Dispose method is already overriden in our <form>.designer.cs file. We have to just update with our components which we are using in our form. These components are basically "composite" objects in your form.
0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

Recently while returning home from work my wife (another .NET developer) was murmuring something. On further poking she said that she has been assigned a task where she has to serialize and deserialize objects and she is afraid of serialization. Wha…
Parsing a CSV file is a task that we are confronted with regularly, and although there are a vast number of means to do this, as a newbie, the field can be confusing and the tools can seem complex. A simple solution to parsing a customized CSV fi…
It is a freely distributed piece of software for such tasks as photo retouching, image composition and image authoring. It works on many operating systems, in many languages.
Here's a very brief overview of the methods PRTG Network Monitor (https://www.paessler.com/prtg) offers for monitoring bandwidth, to help you decide which methods you´d like to investigate in more detail.  The methods are covered in more detail in o…

743 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

15 Experts available now in Live!

Get 1:1 Help Now