C
carl.clawson
The StatusStrip control leaks when you clear its Items collection. You
can try the code below. Yes, this looks like an odd way to use a
progress bar but I distilled this snippet from a moderately large
application that was running out of user handles (10000 max) after
some hours of use because of just this problem. Try it. Just make a
form with a timer, a button, a label, and a StatusStrip. Push the
button and you will see it leak user handles in the task manager.
Workaround: Explicitly dispose each toolstrip item before clearing the
collection. Set DONT_LEAK = True to do this.
Is there a better way to solve the problem? Please tell me.
I found a few articles on MSDN about leaks with StatusStrips but none
of them appear related to this. In particular I have AllowItemReorder
= False, so this is not the problem that was reported to occur when
you have that set True.
Thanks for listening,
Carl
Public Class Form1
Private Const DONT_LEAK As Boolean = False
Private progressCount As Integer
Private progressTarget As Integer = 20000
Private Sub cmdThrashStrip_Click(ByVal sender As System.Object,
ByVal e As System.EventArgs) Handles cmdThrashStrip.Click
progressCount = 0
Timer1.Interval = 10
Timer1.Enabled = True
End Sub
Private Sub UpdateProgress()
Try
If DONT_LEAK Then
' Disposing directly from collections gives
"collection modified" exception
' from enumerator
Dim killList As New Generic.List(Of ToolStripItem)
For Each item As ToolStripItem In StatusStrip1.Items
killList.Add(item)
Next
StatusStrip1.Items.Clear()
For Each item As ToolStripItem In killList
item.Dispose()
Next
Else
StatusStrip1.Items.Clear()
End If
Dim pb As New ToolStripProgressBar
pb.Value = 100 * progressCount / progressTarget
StatusStrip1.Items.Add(pb)
If progressCount >= progressTarget Then
Timer1.Enabled = False
StatusStrip1.Items.Add("Done")
End If
Catch ex As Exception
' Ha! No handle left to even put up a message box!
Label1.Text = ex.Message
End Try
End Sub
Private Sub Timer1_Tick(ByVal sender As Object, ByVal e As
System.EventArgs) Handles Timer1.Tick
progressCount += 1
UpdateProgress()
End Sub
End Class
can try the code below. Yes, this looks like an odd way to use a
progress bar but I distilled this snippet from a moderately large
application that was running out of user handles (10000 max) after
some hours of use because of just this problem. Try it. Just make a
form with a timer, a button, a label, and a StatusStrip. Push the
button and you will see it leak user handles in the task manager.
Workaround: Explicitly dispose each toolstrip item before clearing the
collection. Set DONT_LEAK = True to do this.
Is there a better way to solve the problem? Please tell me.
I found a few articles on MSDN about leaks with StatusStrips but none
of them appear related to this. In particular I have AllowItemReorder
= False, so this is not the problem that was reported to occur when
you have that set True.
Thanks for listening,
Carl
Public Class Form1
Private Const DONT_LEAK As Boolean = False
Private progressCount As Integer
Private progressTarget As Integer = 20000
Private Sub cmdThrashStrip_Click(ByVal sender As System.Object,
ByVal e As System.EventArgs) Handles cmdThrashStrip.Click
progressCount = 0
Timer1.Interval = 10
Timer1.Enabled = True
End Sub
Private Sub UpdateProgress()
Try
If DONT_LEAK Then
' Disposing directly from collections gives
"collection modified" exception
' from enumerator
Dim killList As New Generic.List(Of ToolStripItem)
For Each item As ToolStripItem In StatusStrip1.Items
killList.Add(item)
Next
StatusStrip1.Items.Clear()
For Each item As ToolStripItem In killList
item.Dispose()
Next
Else
StatusStrip1.Items.Clear()
End If
Dim pb As New ToolStripProgressBar
pb.Value = 100 * progressCount / progressTarget
StatusStrip1.Items.Add(pb)
If progressCount >= progressTarget Then
Timer1.Enabled = False
StatusStrip1.Items.Add("Done")
End If
Catch ex As Exception
' Ha! No handle left to even put up a message box!
Label1.Text = ex.Message
End Try
End Sub
Private Sub Timer1_Tick(ByVal sender As Object, ByVal e As
System.EventArgs) Handles Timer1.Tick
progressCount += 1
UpdateProgress()
End Sub
End Class