|
-
Jul 13th, 2011, 10:00 PM
#1
Thread Starter
Hyperactive Member
[RESOLVED] Hanging out.
Hi All,
I'm having an issue with a program.
It seems to run (continuously) any amount of time from a few days to about a week.
Eventually, and seemingly randomly I get the following Errror. None of the users see a consistent item that is causing the hang, and sometimes it's even just running with no interaction with the user.
AppHangB1
Hang Type 4.
I just get long signature alpha numerics as a debugging tool.
Is there any way to
a) force my program to kick out of the hang if it detects one, (and I guess, how could I write a separate thread to detect a hang?)
b) find out where my program is hanging?
c) if none of these options are viable, some coding practices I might be doing wrong that I could change to help avoid this?
Thanks in advance,
Nick
-
Jul 13th, 2011, 10:22 PM
#2
Re: Hanging out.
Ok, this program is designed to run pretty much 24/7? Are you instancing any "permanent" objects that aren't Forms or classed as Modules? The reason I ask is even though you may have a form or a module instancing some objects, if they sit around long enough unused, they may get scrubbed by the internal garbage collect mechanisms present in the managed system.
For example:
I load a form, the form on open creates an instance of a class object. I interact with the program which gives the class object usage. Then, I walk away for 2 days. During that time, that class object can get wiped out by the garbage collect. I come back and try to use the program, it tries to use the class object which was never officially disposed, and because the GC got it, my program crashes.
To solve this issue, you need to override a function called InitializeLifetimeService()
Code:
Inherits MarshalByRefObject
Public Overrides Function InitializeLifetimeService() As Object
Return Nothing
End Function
Returning "Nothing" will ensure the object NEVER gets wiped by the GC unless you close the program or call a .Dispose method.
Now, the only other thing I can think of that could cause a hang or a freeze like this might be a memory leak. Are you properly disposing your old objects? If the program is being continually used for several days at a time, undisposed objects may build up and eventually cause issues.
-
Jul 14th, 2011, 10:17 AM
#3
Thread Starter
Hyperactive Member
Re: Hanging out.
Hi Jenner,
You are quite correct, this is designed to run 24/7
Thank you so much for your detailed answer; I will add the override to all of my classes.
Can you explain a little be further about how I should or should not be disposing of objects? Once I create an instance of an object in this program, I do not dispose of it until the program closes, however I have quite a few DIM statements that are only set to create a variable with in the scope of a sub routine. Could these be building up problems?
Thanks,
Nick
-
Jul 14th, 2011, 10:26 AM
#4
Thread Starter
Hyperactive Member
Re: Hanging out.
Also, I have a few classes that I use in a similar manner to a "Module"
i.e. they are never instanced, they just have public shared items.
Could this be causing an issue as well?
-
Jul 14th, 2011, 12:22 PM
#5
-
Jul 14th, 2011, 02:05 PM
#6
Thread Starter
Hyperactive Member
Re: Hanging out.
Hi,
I have added the Marshal by Ref Object into my code.
I have several custom collection classes I use, and as they are already inheriting I cannot add the inherits tag.
Code:
Public Class clsCurveDataCollection
Inherits System.Collections.ObjectModel.Collection(Of clsCurveData)
End Class
Any ideas on how to keep this from going away via the GC?
-
Jul 14th, 2011, 03:00 PM
#7
Re: Hanging out.
For normal classes if I'm not inheriting anything else:
Code:
Public Class MyClass
Inherits MarshalByRefObject
Implements IDisposable
Public Overrides Function InitializeLifetimeService() As Object
If disposedValue Then
Return MyBase.InitializeLifetimeService()
Else
Return Nothing
End If
End Function
Private disposedValue As Boolean = False ' To detect redundant calls
' IDisposable
Protected Overridable Sub Dispose(ByVal disposing As Boolean)
If Not Me.disposedValue Then
If disposing Then
Try
'Cleanup code here
Catch ex As Exception
Finally
If t IsNot Nothing AndAlso t.IsAlive Then t.Abort()
End Try
End If
' TODO: free your own state (unmanaged objects).
' TODO: set large fields to null.
End If
Me.disposedValue = True
End Sub
#Region " IDisposable Support "
' This code added by Visual Basic to correctly implement the disposable pattern.
Public Sub Dispose() Implements IDisposable.Dispose
' Do not change this code. Put cleanup code in Dispose(ByVal disposing As Boolean) above.
Dispose(True)
GC.SuppressFinalize(Me)
End Sub
#End Region
End Class
If I'm inheriting something that already has a .Dispose() method, then there's similar code already behind the scenes. If I'm inheriting something without a .Dispose() method, then I don't worry about it. I've never had a List object clean out on me.
Also, you shouldn't do this for EVERY object you have. Only ones that are going to be sitting around for a long time in an idle state. If my main form has
Code:
Public Class frmMain
Private mc As MyClass
Private Sub frmMainMenu_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim oc As OtherClass
With oc
oc.DoStuff()
End With
oc.Dispose
End Sub
End Class
I would include the LifeTime code in the "MyClass" object, but not in the "OtherClass" object, since this is getting cleaned up at the end of the function block anyways. I'll still use IDisposable though in all my objects since this is good practice.
For an inherited list, I only implement IDisposable, here's an example of one that implements Clone and Dispose (because Clone is always nice to have too ):
Code:
Public Class MyObjectList
Inherits List(Of MyObject)
Implements ICloneable
Implements IDisposable
Public Function Clone() As Object Implements System.ICloneable.Clone
Dim newMOL As New MyObjectList
For Each ob In Me
newMOL.Add(New MyObject With {.Property1 = ob.Property1, .Property2 = ob.Property2})
Next
Return newMOL
End Function
Private disposedValue As Boolean = False ' To detect redundant calls
' IDisposable
Protected Overridable Sub Dispose(ByVal disposing As Boolean)
If Not Me.disposedValue Then
If disposing Then
For Each ob In Me
ob.Dispose()
Next
End If
' TODO: free your own state (unmanaged objects).
' TODO: set large fields to null.
End If
Me.disposedValue = True
End Sub
#Region " IDisposable Support "
' This code added by Visual Basic to correctly implement the disposable pattern.
Public Sub Dispose() Implements IDisposable.Dispose
' Do not change this code. Put cleanup code in Dispose(ByVal disposing As Boolean) above.
Dispose(True)
GC.SuppressFinalize(Me)
End Sub
#End Region
End Class
-
Jul 14th, 2011, 06:21 PM
#8
Thread Starter
Hyperactive Member
Re: Hanging out.
Before I close out the thread, does anyone know what a type 4 hang is vs. other types?
Also, people mention stack traces after a hang, how do I get that information?
Thanks so much Jenner for all of your help; I'm implementing your suggestions and will post back if there is any change in hang frequency. So far so good, but it has only been a day.
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
|