luiggye
asked on
Why a windows form is not disposed ?
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(M em.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(M em.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.ShowDi alog() '----- this form have not any code
TestFormWithoutCode.dispos e()
GC.Collect()
If TestFormWithoutCode.IsDisp osed Then
msgbox("The form is not disposed")
End If
TestFormWithoutCode.IsDisp osed ALLWAYS RETURN FALSE TOO..!!
What are happening?
How I can do to REALLY DISPOSE a form?
In my case, I believe that the SetProcessWorkingSetSize(M em.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.
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(M
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(M
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.ShowDi
TestFormWithoutCode.dispos
GC.Collect()
If TestFormWithoutCode.IsDisp
msgbox("The form is not disposed")
End If
TestFormWithoutCode.IsDisp
What are happening?
How I can do to REALLY DISPOSE a form?
In my case, I believe that the SetProcessWorkingSetSize(M
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.
(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.
ASKER
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.Debugg erNonUserC ode()> _
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.
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.Debugg
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
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
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
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
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.
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.
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.