.NET Forum / Languages / VB.NET / March 2008
Object destruction VB.NET 2005
|
|
Thread rating:  |
Sid Price - 13 Feb 2008 22:38 GMT 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.
Scott M. - 13 Feb 2008 22:54 GMT 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
> Hi everyone, > I have a class that creates a thread for some I/O that blocks in the [quoted text clipped - 8 lines] > Any suggestions please? > Sid. Sid Price - 13 Feb 2008 23:20 GMT 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.
> You should implement the IDisposable interface with a proper > Dispose/Finalize pattern. As a rule, you don't actually put your clean up [quoted text clipped - 21 lines] >> Any suggestions please? >> Sid. Jack Jackson - 14 Feb 2008 01:03 GMT How and where is the object created?
If it is in a form, dispose it in the form's Dispose.
>Hi Scott, >I tried implementing IDisposable in my class and when I close the [quoted text clipped - 29 lines] >>> Any suggestions please? >>> Sid. Sid Price - 14 Feb 2008 01:14 GMT 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.
> How and where is the object created? > [quoted text clipped - 42 lines] >>>> Any suggestions please? >>>> Sid. Jack Jackson - 14 Feb 2008 01:56 GMT 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.
>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 [quoted text clipped - 48 lines] >>>>> Any suggestions please? >>>>> Sid. Sid Price - 14 Feb 2008 17:06 GMT Thank you for the advice, Sid.
>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 [quoted text clipped - 61 lines] >>>>>> Any suggestions please? >>>>>> Sid. (O)enone - 14 Feb 2008 09:46 GMT > 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.
 Signature (O)enone
Sid Price - 14 Feb 2008 17:07 GMT 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.
>> Thanks for the suggestion; However, I am writing a class library and >> trying to avoid the user having to call some "Close" or "Dispose" [quoted text clipped - 10 lines] > many other forward steps offered by .NET have led me to overlook this > irritation. Scott M. - 14 Feb 2008 23:30 GMT 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
> 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. [quoted text clipped - 52 lines] >>>>> Any suggestions please? >>>>> Sid. Just_a_fan@home.net - 01 Mar 2008 00:41 GMT 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
On Thu, 14 Feb 2008 18:30:01 -0500, in microsoft.public.dotnet.languages.vb "Scott M." <smar@nospam.nospam> wrote:
>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 [quoted text clipped - 79 lines] >>>>>> Any suggestions please? >>>>>> Sid. Scott M. - 01 Mar 2008 22:56 GMT 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
> Is there a discussion of what is "managed" and what is "unmanaged" > somewhere? [quoted text clipped - 105 lines] >>>>>>> Any suggestions please? >>>>>>> Sid. kimiraikkonen - 02 Mar 2008 09:15 GMT On Mar 1, 2:41 am, Just_a_...@home.net wrote:
> Is there a discussion of what is "managed" and what is "unmanaged" > somewhere? [quoted text clipped - 93 lines] > >>>>>> Any suggestions please? > >>>>>> Sid. Managed objects / resources can be disposed directly using .NET's dispose() or close()..., however unmanageds' disposal is different: http://www.devcity.net/PrintArticle.aspx?ArticleID=93 http://msdn2.microsoft.com/en-us/library/b1yfkh5e(vs.71).aspx
Cor Ligthert[MVP] - 14 Feb 2008 18:18 GMT A thread stops simple with thread.abort, not much more, however that does mean that the destruction process starts.
Cor
Tom Shelton - 14 Feb 2008 19:34 GMT > 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.
 Signature Tom Shelton
Sid Price - 14 Feb 2008 23:16 GMT 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,
>> A thread stops simple with thread.abort, not much more, however that does >> mean that the destruction process starts. [quoted text clipped - 13 lines] > then exit the method. The exiting of the method will cause the thread > to be cleaned up anyway. Tom Shelton - 15 Feb 2008 00:00 GMT > Gentlemen, > The issue was not aborting my I/O thread, it was placing the code for [quoted text clipped - 6 lines] > 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 :)
 Signature Tom Shelton
Cor Ligthert[MVP] - 15 Feb 2008 04:58 GMT 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
>> A thread stops simple with thread.abort, not much more, however that does >> mean that the destruction process starts. [quoted text clipped - 13 lines] > then exit the method. The exiting of the method will cause the thread > to be cleaned up anyway. Sid Price - 17 Feb 2008 01:33 GMT 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.
> Tom, > [quoted text clipped - 25 lines] >> then exit the method. The exiting of the method will cause the thread >> to be cleaned up anyway.
Free MagazinesGet these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...
|
|
|