|
-
Jan 23rd, 2011, 01:27 PM
#1
Thread Starter
Member
ping.sendasync memory leak
Hi All,
I'm having a strange issue with a memory leak associated with ping.sendasync. My program has a section in it that allows the user to specify X number of servers/computers to monitor. About every 30 seconds it will execute a routine that loops through the list and sends a ping asynchronously to each server/computer.
If I keep an eye on the process memory usage in the task manager it will creep up about 1-1.5MB each time the routine is executed. Now, this program will be used and left running for hours and hours for each person, and over the course of the day the mem usage can creep up close to a gig...... (it happened the other day until I noticed it)
See the code below for an idea of what I'm doing, note that I AM calling .dispose and in the async case I am directcasting idisposable first and then disposing as recommended on several other sites. I'm also telling the GC to collect after as well.
Server Indicators routine (starts the ping.sendasync):
Code:
Public Sub ServerIndicators()
ReloadingServers = True
ServerStatusDG.Sort(ServerStatusDG.Columns(ServerStatusDG.Columns.Item("ServerName").Index), ListSortDirection.Ascending)
Dim myPing As New Ping
For Each ipAddy As String In My.Settings.ServerStatusCollection
' Generate the request
myPing = New Ping()
' Add the handler for this request...
AddHandler myPing.PingCompleted, AddressOf PingRequestCompleted
myPing.SendAsync(ipAddy, 1000, ipAddy)
CType(myPing, IDisposable).Dispose()
myPing = Nothing
Next
If Not ServerStatusDG.SelectedRows.Count > 0 Then
ServerStatusDG.ClearSelection()
End If
GC.Collect()
ReloadingServers = False
End Sub
PingrequestCompleted: (check if online - loop through dgv and update that server, else report offline and find it in the dgv)
Code:
Public Sub PingRequestCompleted(ByVal sender As Object, ByVal e As Net.NetworkInformation.PingCompletedEventArgs)
' When received, add the approrpiate entry into the dgv
Try
If e.Error IsNot Nothing Then
GoTo offline
End If
If e.Reply.Status = 0 Then
'set green arrow
If ServerStatusOfflineArray.Contains(e.UserState.ToString) Then
ServerStatusOfflineArray.Remove(e.UserState.ToString)
End If
For i = 0 To ServerStatusDG.Rows.Count - 1
If ServerStatusDG.Rows(i).Cells(ServerStatusDG.Columns.Item("ServerName").Index).Value = e.UserState.ToString Then
If Not ServerStatusDG.Rows(i).Cells(ServerStatusDG.Columns.Item("ServerStatusimg").Index).Value Is My.Resources.SuccessGreen Then
ServerStatusDG.Rows(i).Cells(ServerStatusDG.Columns.Item("ServerStatusimg").Index).Value = My.Resources.SuccessGreen
End If
ServerStatusDG.Rows(i).Cells(ServerStatusDG.Columns.Item("FavoritesIPAddress").Index).Value = e.Reply.Address
If e.Reply.RoundtripTime > 100 Then
ServerStatusDG.Rows(i).Cells(ServerStatusDG.Columns.Item("ServerLatency").Index).Style.ForeColor = Color.IndianRed
ServerStatusDG.Rows(i).Cells(ServerStatusDG.Columns.Item("ServerLatency").Index).Value = e.Reply.RoundtripTime & "ms"
Else
ServerStatusDG.Rows(i).Cells(ServerStatusDG.Columns.Item("ServerLatency").Index).Style.ForeColor = Color.LimeGreen
If e.Reply.RoundtripTime = 0 Then
ServerStatusDG.Rows(i).Cells(ServerStatusDG.Columns.Item("ServerLatency").Index).Value = "<1ms"
Else
ServerStatusDG.Rows(i).Cells(ServerStatusDG.Columns.Item("ServerLatency").Index).Value = e.Reply.RoundtripTime & "ms"
End If
End If
Exit For
End If
Next
GoTo skip
Else
GoTo offline
End If
offline:
'set red image
For i = 0 To ServerStatusDG.Rows.Count - 1
If ServerStatusDG.Rows(i).Cells(ServerStatusDG.Columns.Item("ServerName").Index).Value = e.UserState.ToString Then
ServerStatusDG.Rows(i).Cells(ServerStatusDG.Columns.Item("ServerStatusimg").Index).Value = My.Resources.ErrorRed
ServerStatusDG.Rows(i).Cells(ServerStatusDG.Columns.Item("ServerStatusimg").Index).Value = Nothing
ServerStatusDG.Rows(i).Cells(ServerStatusDG.Columns.Item("ServerLatency").Index).Value = Nothing
Exit For
End If
Next
If Not ServerStatusOfflineArray.Contains(e.UserState.ToString) Then
If My.Settings.OfflineAlerts = True Then
nfi.BalloonTipIcon = ToolTipIcon.Error
nfi.BalloonTipTitle = "Offline Alert"
nfi.BalloonTipText = e.UserState.ToString & " is not responding!"
nfi.ShowBalloonTip(30000)
End If
ServerStatusOfflineArray.Add(e.UserState.ToString)
End If
skip:
If ServerStatusOfflineArray.Count = 0 Then
vNavPaneServerStatus.Image = Nothing
vNavPaneServerStatus.HeaderText = "Favorites"
Else
vNavPaneServerStatus.Image = My.Resources.errorRedDot_navpane
vNavPaneServerStatus.HeaderText = "Favorites - " & ServerStatusOfflineArray.Count & " Offline"
End If
vNavPaneServerStatus.Refresh()
If Not ServerStatusDG.SelectedRows.Count > 0 Then
ServerStatusDG.ClearSelection()
End If
Catch ex As Exception
Finally
CType(sender, IDisposable).Dispose()
End Try
End Sub
So it will loop through a datagridview and update the values each time... anything you guys can think of will help. I only started having this problem when I switched to ping.sendasync method.
I have seen this blog post about this problem... but implementing that seemed to do nothing: http://blogs.msdn.com/b/joncole/arch...sendasync.aspx
Thanks!
Last edited by Drewster727; Jan 23rd, 2011 at 04:11 PM.
-
Jan 24th, 2011, 02:14 PM
#2
Thread Starter
Member
Re: ping.sendasync memory leak
-
Jan 24th, 2011, 03:39 PM
#3
Re: ping.sendasync memory leak
Could it be because you are creating one that you don't dispose? Look at the top of your method, you Dim myPing as New Ping and then in your loop you create another one, essentially orphaning that first one. Trying changing it to Dim myPing as Ping and see if that helps.
-
Jan 24th, 2011, 04:37 PM
#4
Thread Starter
Member
Re: ping.sendasync memory leak
Thanks for the reply,
unfortunately the problem still exists... each time it loops through the list the process mem usage jumps about 1MB...
here is my loop adjusted:
Code:
For Each ipAddy As String In My.Settings.ServerStatusCollection
Dim myPing As New Ping
' Add the handler for this request...
AddHandler myPing.PingCompleted, AddressOf PingRequestCompleted
myPing.SendAsync(ipAddy, 1000, ipAddy)
CType(myPing, IDisposable).Dispose()
myPing = Nothing
Next
-
Jan 25th, 2011, 02:00 AM
#5
Re: ping.sendasync memory leak
Kind of a pointless loop. You should be disposing in the PingRequestCompleted sub. It should pass the sender along with it, allowing you to dispose of it and set it to nothing.
-
Jan 28th, 2011, 04:51 PM
#6
Thread Starter
Member
Re: ping.sendasync memory leak
thanks for the response,
I actually am running dispose in the pingrequestcompleted routine.
Code:
CType(sender, IDisposable).Dispose()
the mem usage is still creeping up...
Anyone have any ideas?? this one is bothering me.. pingasync would work really well if I wasnt having this problem haha
-
Jan 28th, 2011, 04:57 PM
#7
Thread Starter
Member
Re: ping.sendasync memory leak
also added this on at the end of my pingrequestcompleted routine:
Code:
With DirectCast(sender, Ping)
RemoveHandler .PingCompleted, AddressOf PingRequestCompleted
.Dispose()
End With
still have the memory leak...
-
Jan 28th, 2011, 04:58 PM
#8
Re: ping.sendasync memory leak
Try removing the handler and calling GC.Collect() in the completed stub.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|