469,572 Members | 1,306 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,572 developers. It's quick & easy.

Problem with "handles" - possible garbage collection issue?

I have a problem in my application which I believe is due to open handles.. .

The symptom that users report is that after they have been using the application for a while, it will randomly just crash with an exception report (I've not got the details of the error, but I'm working on that now!).

I'm trying to reproduce the circumstances by simulating a typical batch of user tasks on my pc and monitoring whats happening. I'm guessing it's some problem with threads/handles or something so I've opened up the task manager and added all the available columns.

What I've noticed is that whilst the application is running, the memory usage keeps increasing, but more worrying, the no of open handles just keeps going up and up (it's nearly 4000 handles after running through about 30 tasks).

What the application is doing is as follows:

I have a main form showing, which displays a list from a database.

Then what I'm doing is clicking down the list one by one..

What this does is to open a form on another thread to stop it blocking the main window. It does this as follows

=====
Private sub Click(rowno as int32)
dim vehicle as new dmsvehicle.vehicle
vehicle.showvehicle(Data(rowno))
end sub
=====

The Vehicle.showvehicle subroutine is as follows:

====
public sub ShowVehicle(StockNo)
Dim frm As New ViewVehicleStatus(StockNo)

Dim t As New Threading.Thread(AddressOf frm.dmsShowDialog)

'frm.StockNo = StockNo

t.Start()

end Sub

====

The "dmsShowDialog" subroutine in the form is simply doing a me.showdialog.

This all seems to work fine, and when I close the form I see a message such as "The thread '<No Name>' (0x6ec) has exited with code 0 (0x0)." appear in the output window of the development environment.

However, the no of handles just keeps increasing - I presumed that the garbage collector should tidy up every now and then, but thats not what I'm seeing.

I've not actually duplicated the users issue yet (but I have a high spec machine with masses of memory), but I suspect that this will be the cause of their problem?

Any suggestions as to what I've done wrong?

Thanks in advance

Simon


Nov 21 '05 #1
7 2377
"Simon Verona" <ne**@aphroditeuk.com> schrieb
I have a problem in my application which I believe is due to open
handles.. .

The symptom that users report is that after they have been using the
application for a while, it will randomly just crash with an
exception report (I've not got the details of the error, but I'm
working on that now!).

I'm trying to reproduce the circumstances by simulating a typical
batch of user tasks on my pc and monitoring whats happening. I'm
guessing it's some problem with threads/handles or something so I've
opened up the task manager and added all the available columns.

What I've noticed is that whilst the application is running, the
memory usage keeps increasing, but more worrying, the no of open
handles just keeps going up and up (it's nearly 4000 handles after
running through about 30 tasks).

What the application is doing is as follows:

I have a main form showing, which displays a list from a database.

Then what I'm doing is clicking down the list one by one..

What this does is to open a form on another thread to stop it
blocking the main window. It does this as follows

=====
Private sub Click(rowno as int32)
dim vehicle as new dmsvehicle.vehicle
vehicle.showvehicle(Data(rowno))
end sub
=====

The Vehicle.showvehicle subroutine is as follows:

====
public sub ShowVehicle(StockNo)
Dim frm As New ViewVehicleStatus(StockNo)

Dim t As New Threading.Thread(AddressOf frm.dmsShowDialog)

'frm.StockNo = StockNo

t.Start()

end Sub

====

The "dmsShowDialog" subroutine in the form is simply doing a
me.showdialog.

This all seems to work fine, and when I close the form I see a
message such as "The thread '<No Name>' (0x6ec) has exited with code
0 (0x0)." appear in the output window of the development
environment.

However, the no of handles just keeps increasing - I presumed that
the garbage collector should tidy up every now and then, but thats
not what I'm seeing.

I've not actually duplicated the users issue yet (but I have a high
spec machine with masses of memory), but I suspect that this will be
the cause of their problem?

Any suggestions as to what I've done wrong?

Thanks in advance

You are creating the Form in the wrong thread. You must create it in the
thread that you started and that calls Showdialog.

I don't know if it solve the handles problem. Maybe you don't call Dispose
on all created resources.

Armin

Nov 21 '05 #2
I'm deliberately creating the form on the new thread to make the call to
open the form non-blocking. If I didn't create a new thread, then with the
new form open, the original form would block awaiting it to close.

Am I doing this wrong? Is there an alternative way to do this?

I don't use the "dispose" method at all in my code, I presumed that when the
thread died, the garbage collector would tidy up all the resources used by
that thread.. Have I got this wrong?

Regards
Simon
"Armin Zingler" <az*******@freenet.de> wrote in message
news:eN**************@TK2MSFTNGP09.phx.gbl...
"Simon Verona" <ne**@aphroditeuk.com> schrieb
I have a problem in my application which I believe is due to open
handles.. .

The symptom that users report is that after they have been using the
application for a while, it will randomly just crash with an
exception report (I've not got the details of the error, but I'm
working on that now!).

I'm trying to reproduce the circumstances by simulating a typical
batch of user tasks on my pc and monitoring whats happening. I'm
guessing it's some problem with threads/handles or something so I've
opened up the task manager and added all the available columns.

What I've noticed is that whilst the application is running, the
memory usage keeps increasing, but more worrying, the no of open
handles just keeps going up and up (it's nearly 4000 handles after
running through about 30 tasks).

What the application is doing is as follows:

I have a main form showing, which displays a list from a database.

Then what I'm doing is clicking down the list one by one..

What this does is to open a form on another thread to stop it
blocking the main window. It does this as follows

=====
Private sub Click(rowno as int32)
dim vehicle as new dmsvehicle.vehicle
vehicle.showvehicle(Data(rowno))
end sub
=====

The Vehicle.showvehicle subroutine is as follows:

====
public sub ShowVehicle(StockNo)
Dim frm As New ViewVehicleStatus(StockNo)

Dim t As New Threading.Thread(AddressOf frm.dmsShowDialog)

'frm.StockNo = StockNo

t.Start()

end Sub

====

The "dmsShowDialog" subroutine in the form is simply doing a
me.showdialog.

This all seems to work fine, and when I close the form I see a
message such as "The thread '<No Name>' (0x6ec) has exited with code
0 (0x0)." appear in the output window of the development
environment.

However, the no of handles just keeps increasing - I presumed that
the garbage collector should tidy up every now and then, but thats
not what I'm seeing.

I've not actually duplicated the users issue yet (but I have a high
spec machine with masses of memory), but I suspect that this will be
the cause of their problem?

Any suggestions as to what I've done wrong?

Thanks in advance

You are creating the Form in the wrong thread. You must create it in the
thread that you started and that calls Showdialog.

I don't know if it solve the handles problem. Maybe you don't call Dispose
on all created resources.

Armin

Nov 21 '05 #3
Why dont you try a form.dispose, when you return from the showdialog and see
if that solves the handle problem?

--
Rgds,
Anand
VB.NET MVP
http://www.dotnetindia.com
"Simon Verona" wrote:
I have a problem in my application which I believe is due to open handles.. .

The symptom that users report is that after they have been using the application for a while, it will randomly just crash with an exception report (I've not got the details of the error, but I'm working on that now!).

I'm trying to reproduce the circumstances by simulating a typical batch of user tasks on my pc and monitoring whats happening. I'm guessing it's some problem with threads/handles or something so I've opened up the task manager and added all the available columns.

What I've noticed is that whilst the application is running, the memory usage keeps increasing, but more worrying, the no of open handles just keeps going up and up (it's nearly 4000 handles after running through about 30 tasks).

What the application is doing is as follows:

I have a main form showing, which displays a list from a database.

Then what I'm doing is clicking down the list one by one..

What this does is to open a form on another thread to stop it blocking the main window. It does this as follows

=====
Private sub Click(rowno as int32)
dim vehicle as new dmsvehicle.vehicle
vehicle.showvehicle(Data(rowno))
end sub
=====

The Vehicle.showvehicle subroutine is as follows:

====
public sub ShowVehicle(StockNo)
Dim frm As New ViewVehicleStatus(StockNo)

Dim t As New Threading.Thread(AddressOf frm.dmsShowDialog)

'frm.StockNo = StockNo

t.Start()

end Sub

====

The "dmsShowDialog" subroutine in the form is simply doing a me.showdialog.

This all seems to work fine, and when I close the form I see a message such as "The thread '<No Name>' (0x6ec) has exited with code 0 (0x0)." appear in the output window of the development environment.

However, the no of handles just keeps increasing - I presumed that the garbage collector should tidy up every now and then, but thats not what I'm seeing.

I've not actually duplicated the users issue yet (but I have a high spec machine with masses of memory), but I suspect that this will be the cause of their problem?

Any suggestions as to what I've done wrong?

Thanks in advance

Simon


Nov 21 '05 #4
"Simon Verona" <ne**@aphroditeuk.com> schrieb
I'm deliberately creating the form on the new thread to make the
call to open the form non-blocking. If I didn't create a new
thread, then with the new form open, the original form would block
awaiting it to close.
I did not write you shouldn't create another thread.

What is the reason why you open the Form modally? If you open it modeless
you don't need another thread and you can still work with the previous form.
It is usually not necessary to open Forms in different threads. If there's
work to do that would block the Form(s), you might consider putting only the
work into a different thread.
Am I doing this wrong? Is there an alternative way to do this?
If you want to open it in another thread, I'd also create it there
(quick&dirty):

public sub ShowVehicle(StockNo)
Dim bla As New viewthread
bla.start(stockno)
end Sub

class viewthread
private t as thread
private stockno as stockno

public sub start(StockNo as ?)
me.stockno = stockno
t = new thread(addressof threadmain)
t.start
end sub

private sub threadmain
Dim frm As New ViewVehicleStatus(me.StockNo)
application.run(frm)
end sub
end class

The class is there to be able to pass data (stockno) to the thread.

I don't use the "dispose" method at all in my code, I presumed that
when the thread died, the garbage collector would tidy up all the
resources used by that thread.. Have I got this wrong?


Yep. Threads, or execution flow in general, has no relation to data and
memory management.

Maybe objects from died threads are collected earlier, but I don't think so.
See also:
http://msdn.microsoft.com/library/en...management.asp

The m.p.d.framework.clr group is probably the best place to ask for details.
Armin

Nov 21 '05 #5
Ok

I open the form modally because if I don't - ie use frm.show then the form
flips open and the immediately disappears again and the thread dies straight
away.

However, application.run(frm) seems to do the same thing as opening it
modally...

I've re-engineered my code to use the format for creating the thread as you
describe. It still uses handles each time I open the form using this
method, though the thread count increases by one as the form opens and then
decreases again when it is closed... I guess that there are some
sub-objects somewhere that it believes are not ready to dispose of, though I
can't think what they might be or where.

I'll try the other newsgroup as you suggest. Thanks for your help.

Regards
Simon
"Armin Zingler" <az*******@freenet.de> wrote in message
news:%2****************@TK2MSFTNGP14.phx.gbl...
"Simon Verona" <ne**@aphroditeuk.com> schrieb
I'm deliberately creating the form on the new thread to make the
call to open the form non-blocking. If I didn't create a new
thread, then with the new form open, the original form would block
awaiting it to close.


I did not write you shouldn't create another thread.

What is the reason why you open the Form modally? If you open it modeless
you don't need another thread and you can still work with the previous
form. It is usually not necessary to open Forms in different threads. If
there's work to do that would block the Form(s), you might consider
putting only the work into a different thread.
Am I doing this wrong? Is there an alternative way to do this?


If you want to open it in another thread, I'd also create it there
(quick&dirty):

public sub ShowVehicle(StockNo)
Dim bla As New viewthread
bla.start(stockno)
end Sub

class viewthread
private t as thread
private stockno as stockno

public sub start(StockNo as ?)
me.stockno = stockno
t = new thread(addressof threadmain)
t.start
end sub

private sub threadmain
Dim frm As New ViewVehicleStatus(me.StockNo)
application.run(frm)
end sub
end class

The class is there to be able to pass data (stockno) to the thread.

I don't use the "dispose" method at all in my code, I presumed that
when the thread died, the garbage collector would tidy up all the
resources used by that thread.. Have I got this wrong?


Yep. Threads, or execution flow in general, has no relation to data and
memory management.

Maybe objects from died threads are collected earlier, but I don't think
so. See also:
http://msdn.microsoft.com/library/en...management.asp

The m.p.d.framework.clr group is probably the best place to ask for
details.
Armin

Nov 21 '05 #6
"Simon Verona" <ne**@aphroditeuk.com> schrieb
Ok

I open the form modally because if I don't - ie use frm.show then
the form flips open and the immediately disappears again and the
thread dies straight away.

However, application.run(frm) seems to do the same thing as opening
it modally...
No, because you can still use the other Form becaue they are running in
different threads. Still I am not sure why you open them in different
threads.
I've re-engineered my code to use the format for creating the thread
as you describe. It still uses handles each time I open the form
using this method, though the thread count increases by one as the
form opens and then decreases again when it is closed... I
guess that there are some sub-objects somewhere that it believes are
not ready to dispose of, though I can't think what they might be or
where.
You should examine your code to see which disposable objects you create.
After their usage, they should be disposed. If they created native handles
(those you see in task manager), the handles are destroyed immediatelly. If
you don't call dispose, they will be destroyed also, but later when GC is
done.
I'll try the other newsgroup as you suggest. Thanks for your help.


An attempt:

application.run(frm)
gc.collect
gc.waitforpendingfinalizers

just to see what happens. Does it change the behavior you see in the task
manager?

Armin

Nov 21 '05 #7
Simon,
| The symptom that users report is that after they have been using the
| application for a while, it will randomly just crash with an
| exception report (I've not got the details of the error, but
| I'm working on that now!).

You may want to include one or more Global Exception handlers in your
program to log any exception reports from "random" crashes.

Depending on the type of application you are creating, .NET has three
different global exception handlers.

For ASP.NET look at:
System.Web.HttpApplication.Error event
Normally placed in your Global.asax file.

For console applications look at:
System.AppDomain.UnhandledException event
Use AddHandler in your Sub Main.

For Windows Forms look at:
System.Windows.Forms.Application.ThreadException event
Use AddHandler in your Sub Main.

It can be beneficial to combine the above global handlers in your app, as
well as wrap your Sub Main in a try catch itself.

There is an article in the June 2004 MSDN Magazine that shows how to
implement the global exception handling in .NET that explains why & when you
use multiple of the above handlers...

http://msdn.microsoft.com/msdnmag/is...T/default.aspx

For example: In my Windows Forms apps I would have a handler attached to the
Application.ThreadException event, plus a Try/Catch in my Main. The
Try/Catch in Main only catches exceptions if the constructor of the MainForm
raises an exception, the Application.ThreadException handler will catch all
uncaught exceptions from any form/control event handlers.
| What this does is to open a form on another thread to
| stop it blocking the main window. It does this as follows
Why are using Form.ShowDialog on a second thread?

I would simply use Form.Show on the main thread.

Public Sub ShowVehicle(StockNo)

Dim frm As New ViewVehicleStatus(StockNo)

frm.Show()

End Sub

| However, the no of handles just keeps increasing - I presumed that
| the garbage collector should tidy up every now and then,
| but thats not what I'm seeing.

When the user closes a form opened with Show, it will automatically call
Dispose when it is closed. When the user closes a Form opened with
ShowDialog, you need to be certain to call Dispose... Yes the GC will
eventually, at its descrition, call Finalize on the Form, however this may
be long after all the handles have been consumed...

Hope this helps
Jay

"Simon Verona" <ne**@aphroditeuk.com> wrote in message
news:u2**************@TK2MSFTNGP12.phx.gbl...
I have a problem in my application which I believe is due to open handles..
..

The symptom that users report is that after they have been using the
application for a while, it will randomly just crash with an exception
report (I've not got the details of the error, but I'm working on that
now!).

I'm trying to reproduce the circumstances by simulating a typical batch of
user tasks on my pc and monitoring whats happening. I'm guessing it's some
problem with threads/handles or something so I've opened up the task manager
and added all the available columns.

What I've noticed is that whilst the application is running, the memory
usage keeps increasing, but more worrying, the no of open handles just keeps
going up and up (it's nearly 4000 handles after running through about 30
tasks).

What the application is doing is as follows:

I have a main form showing, which displays a list from a database.

Then what I'm doing is clicking down the list one by one..

What this does is to open a form on another thread to stop it blocking the
main window. It does this as follows

=====
Private sub Click(rowno as int32)
dim vehicle as new dmsvehicle.vehicle
vehicle.showvehicle(Data(rowno))
end sub
=====

The Vehicle.showvehicle subroutine is as follows:

====
public sub ShowVehicle(StockNo)
Dim frm As New ViewVehicleStatus(StockNo)

Dim t As New Threading.Thread(AddressOf frm.dmsShowDialog)

'frm.StockNo = StockNo

t.Start()

end Sub

====

The "dmsShowDialog" subroutine in the form is simply doing a me.showdialog.

This all seems to work fine, and when I close the form I see a message such
as "The thread '<No Name>' (0x6ec) has exited with code 0 (0x0)." appear in
the output window of the development environment.

However, the no of handles just keeps increasing - I presumed that the
garbage collector should tidy up every now and then, but thats not what I'm
seeing.

I've not actually duplicated the users issue yet (but I have a high spec
machine with masses of memory), but I suspect that this will be the cause of
their problem?

Any suggestions as to what I've done wrong?

Thanks in advance

Simon



Nov 21 '05 #8

This discussion thread is closed

Replies have been disabled for this discussion.

By using this site, you agree to our Privacy Policy and Terms of Use.