I have Thread (STAThread) in a windows service that does a lot of work. When the Windows service is restarted, I want to gracefully stop this thread.
I know a couple of ways
- Volatile logic
- ManualResetEvent
- CancellationToken
As far as I understand, Thread.Abort is not a race ...
What is the best practice? The work is done in a different class than where the thread starts, so you must either enter the cancelationToken parameter in the constructor, or, for example, have a mutable variable. But I just can’t understand what is the smartest.
Update
To clarify a bit, I wrapped a very simple example of what I'm saying. As mentioned earlier, this is done in the Windows service. Right now I’m thinking of a volatile boolean that is being checked in a loop or cancelationToken .... I can’t wait for the loop to finish, as described below, it can take several minutes, as a result of which the server system administrators think that something is wrong with service, when you need to restart it ... I can easily drop all the work in the loop without problems, however I can not do it with Thread.Abort, this is "evil", and in addition, the COM interface is called, therefore minor cleaning required.
Class Scheduler{ private Thread apartmentThread; private Worker worker; void Scheduling(){ worker = new Worker(); apartmentThread = new Thread(Run); apartmentThread.SetApartmentState(ApartmentState.STA); apartmentThread.Start(); } private void Run() { while (!token.IsCancellationRequested) { Thread.Sleep(pollInterval * MillisecondsToSeconds); if (!token.IsCancellationRequested) { worker.DoWork(); } } } } Class Worker{
UPDATE
Just review the performance using cancelationToken, where the isCancelled state is “checked” in the code, much faster than using waitOne on ManualResetEventSlim. Some quick figures, if when canceling a Token, iterating 100,000,000 times in a loop, it costs me approx. 500 ms, where WaitOne is approx. 3 seconds Thus, the performance in this scenario is faster than cancelationToken.