Domanda

So I am thinking of an instance of a class where I want a thread to run for the life of the class, but terminate when the process that invoked the class is no longer running. This is not the case of a parent thread terminating a child, but a single spinning (in a wait loop perhaps) thread exiting gracefully without holding resources etc.

I think that in C++, you can tell the thread to terminate using a volatile bool from the destructor, however in C# the ~ is not a destructor it is a finalizer. I have not been able to successfully terminate a thread using the finalizer. Perhaps I am missing something there. I know that it is better practice is to have all threads die a natural death without signaling its termination, but it is just not efficient to be spawning a thread each time I need to do something. Yes I know about thread pools, but I think it would be better to have a single listener thread respond to calls to the class, and have it gracefully die when the class is put on the gc.

The real trick is, I think, can I know, or how do I know when the class that is running the thread is first placed on the gc. Is IDisposable what I am looking for? I am not using any unmanaged code here.

È stato utile?

Soluzione

I think you basically have two sensible choices.

Choice One:

If you really don't have any unmanaged resources in use, then you can just let the system close your thread when the program closes. This is obviously the simplest solution.

You only have to worry if you are using objects which have dispose methods that should be called. That includes open files, but probably wouldn't include something like a font.

If you do this, you must ensure that the thread will be running as a "background" thread. The only difference between a background thread and a foreground thread is that when the program closes, all background threads will be automatically terminated - but foreground threads won't.

If you use a Task, by default it will be run as a background thread.

You definitely won't want to do this if your thread will be doing some IO to disk or doing anything else that mustn't be interrupted.

Choice Two:

Add a thread cancellation mechanism, using CancellationTokenSource and arrange to use it at program shutdown, and wait for the thread to exit.

In this case you won't really care whether the thread is foreground or background because you will be managing the program shutdown yourself, and the thread will be stopped properly before the program exits.

If you take this route, you can encapsulate the thread cancellation logic and other thread handling methods in a class that wraps the thread. Then you can add a Dispose() method so you can create the class inside a using block to ensure proper shutdown even in the face of exceptions.

I have taken this approach quite often, and it seems to work quite nicely.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top