Object destruction VB.NET 2005

S

Sid Price

Hi everyone,
I have a class that creates a thread for some I/O that blocks in the absence
of any activity. I need to be able to shut down that thread when the
application using the class closes. I tried putting my code to close the
thread in the Finalize call of the object but when the app closes Finalize
is not called. A simple solution is to create a public "Close" method for
the object however I would have hoped for an automatic method since the
class in question is to be a reusable class library and it seems better
practice for it to clean up when the instances are destroyed without code
needing to be called by the application using the library.
Any suggestions please?
Sid.
 
S

Scott M.

You should implement the IDisposable interface with a proper
Dispose/Finalize pattern. As a rule, you don't actually put your clean up
code in the Finalize method, you put it into a Dispose method. When the
user of the class instantiates it, they can/should use a "Using" block, so
that the object will call Dispose automatically when the end of the Using
block is hit. Or the class user could manually call Dispose when they are
done using it. And, if all else fails, the Finalze method will call Dispose
if/when the object is collected.

http://msdn2.microsoft.com/en-us/library/b1yfkh5e(vs.71).aspx

-Scott
 
S

Sid Price

Hi Scott,
I tried implementing IDisposable in my class and when I close the
application the Dispose method is not being called. If I break using the
debugger the blocked thread is still blocked. Since the object running that
thread is a member of the object I need to dispose will "Dispose" ever get
called before the thread exits?
Sid.
 
J

Jack Jackson

How and where is the object created?

If it is in a form, dispose it in the form's Dispose.
 
S

Sid Price

Thanks for the suggestion; However, I am writing a class library and trying
to avoid the user having to call some "Close" or "Dispose" method. It is the
kind of thing that gets easily forgotten and creates a poor user experience
with the library.
Sid.
 
J

Jack Jackson

I don't think there is anything you can do in the class except to
implement IDisposable. It is the responsibility of the users of your
class to properly dispose instances of it.
 
O

\(O\)enone

Sid said:
Thanks for the suggestion; However, I am writing a class library and
trying to avoid the user having to call some "Close" or "Dispose"
method.

There's unfortunately no way to do this. Users of your class will need to
get in the habit of disposing objects from your class explicitly when they
have finished with them, as they should be doing with all objects that use
unmanaged resources from anywhere else in .NET. The best you can do is
provide a consistent approach to allowing your events to be disposed, and
implementing IDisposable is the correct way to do this.

This is one of the few backward steps from the VB6 COM model IMO. But the
many other forward steps offered by .NET have led me to overlook this
irritation.
 
S

Sid Price

Thank you for the advice,
Sid.

Jack Jackson said:
I don't think there is anything you can do in the class except to
implement IDisposable. It is the responsibility of the users of your
class to properly dispose instances of it.
 
S

Sid Price

Thank you, I agree this seems like a small step backwards but I agree the
benefits of .NEt far out-weight that small issue,
Sid.
 
C

Cor Ligthert[MVP]

A thread stops simple with thread.abort, not much more, however that does
mean that the destruction process starts.

Cor
 
T

Tom Shelton

A thread stops simple with thread.abort, not much more, however that does
mean that the destruction process starts.

Cor

Thread.Abort does not necessarily stop a thread... It is a request to
the thread to stop - and as long as it is in managed code, then that
request will be honered. But, if the thread has moved to unmanaged
code, which I suspect in the OP's case - since it is doing IO of some
kind, then the thread will NOT abort until the thread moves back into
managed code. So, if the thread is doing IO and that IO is blocking, it
will continue indefinately. One method that I have used with blocking
sockets in the past (before I discovered the wonders of async sockets :)
- is to simly to close the socket. Maybe that would work in the OP's
case. Just close the io, and then catch any exceptions that arise and
then exit the method. The exiting of the method will cause the thread
to be cleaned up anyway.
 
S

Sid Price

Gentlemen,
The issue was not aborting my I/O thread, it was placing the code for
aborting the thread etc in a suitable method so that it would get called
when the application using my library closed, i.e. when the class library
object was destroyed.
As you will see from the discussion earlier the only solution was to
implement the IDisposable interface and have the caller (the main
application form) call my "destroy"method.
Not a perfect solution but apparently the best that can be done within .NET.
Sid,
 
S

Scott M.

But Sid, that's the point here. The user of the class MUST take some
responsiblity for using it correctly. Per your earlier reply to me, Dispose
is not going to be automatically called if the application is terminated
prematurely (at least not directly). If you have implemented the
dispose/finalize pattern in the link I provided, Dispose should be
indirectly called by Finalize.

It seems though that you are discussing 2 different things:

1. How to create a class that cleans up after itself so that the class user
doesn't have to worry about cleaning it up.

2. How to get the object to clean itself up in the case of application
termination.

In the case of item #1:
That's exactly what the "Using" statement was introduced for. By using it,
the class user doesn't have to remember to call Dispose. It will be called
automatically when the end of the Using block is reached.

In the case of item #2:
By implementing a proper Dispose/Finalize pattern, the calling of Dispose is
ensured because it is called by Finalize, which will run at application
termination.

-Scott
 
T

Tom Shelton

Gentlemen,
The issue was not aborting my I/O thread, it was placing the code for
aborting the thread etc in a suitable method so that it would get called
when the application using my library closed, i.e. when the class library
object was destroyed.
As you will see from the discussion earlier the only solution was to
implement the IDisposable interface and have the caller (the main
application form) call my "destroy"method.
Not a perfect solution but apparently the best that can be done within .NET.
Sid,

I realize that Sid, I was simply commenting on Cor's statement.
Aborting a thread that is blocking in unmanaged code is not going to
work. To release the thread.

Now, as for the quesiton about finalization... First, when you have a
resorce that needs to be cleaned up, then you will want to use the
IDisposable interface, as has already been discussed - that involved
overriding the Finalize method of your object. Finalize will be called
by the garbage collector:

1) when an object is no longer accessible, unless it has been made
inelligible by calling GC.SuppressFinialize

2) Durring the shutdown of an application domain, even if it is still
accessible.

So, the general pattern is to provide for cleanup via a call to
IDisposable.Dispose and to override Finalize... Now, you want to make
certain that your cleanup code does not throw any exceptions or block
indefinately, as this will cause the finalizers of other object never to
run. One nice thing is that users of your class will be able to us it
in a using block, and so get a bit of determinism :)
 
C

Cor Ligthert[MVP]

Tom,

Thanks for your explanation, that was the main reason I started with the
most simple anser. I was not sure about what the problem of the OP was,
maybe will this bring some light in that situation.

For some reason he seems to be ashame about his code, because he don't want
to show the sligthest piece of it.

Cor
 
S

Sid Price

No not ashamed of the code ... it belongs to my client and I can not post it
here.
Regardless, if you read the rest of the thread you will see that I got some
good advice (thanks again (O)enone) about implementing IDisposable, which I
took, and my issues is resolved.
Sid.
 
J

Just_a_fan

Is there a discussion of what is "managed" and what is "unmanaged"
somewhere?

I am new to this Dispose business and need to know when I need to do
something and when it is handled internally.

Thanks for any pointers.

Mike
 
S

Scott M.

You could search the newsgroups for those terms, but in a nutshell....

Managed objects are objects that are directly controlled by the .NET Common
Language Runtime (CLR). Examples would be System.Windows.Forms.Textbox and
System.Data.DataSet.

Unmanaged objects are objects that are not directly controlled by the CRL.
Examples are: a COM object used via a proxy in .NET or the underlying file
that a .NET StreamReader is interacting with.

-Scott
 
K

kimiraikkonen

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top