Zatrzymywanie wątku, ManualResetEvent, volatile boolean lub cancellationToken
Mam wątek (STAThread) w usłudze Windows, który wykonuje dużą ilość pracy. Po ponownym uruchomieniu usługi Windows chcę zatrzymać ten wątek z wdziękiem.
Znam kilka sposobów
Lotna wartość logicznaManualResetEventCancellationTokenO ile się dowiedziałem, Thread.Abort to nie ma ...
Jaka jest najlepsza praktyka? Praca jest wykonywana w innej klasie niż ta, w której uruchamiany jest wątek, dlatego konieczne jest wprowadzenie parametru cancellationToken w konstruktorze lub na przykład zmiennej lotnej. Ale nie mogę pojąć, co jest najmądrzejsze.
Aktualizacja
Aby trochę wyjaśnić, przedstawiłem bardzo prosty przykład tego, o czym mówię. Jak powiedziano wcześniej, odbywa się to w usłudze Windows. W tej chwili myślę, że zmienna boolean jest sprawdzana w pętli lub cancellationToken .... Nie mogę się doczekać, aż pętla się zakończy, jak stwierdzono poniżej, może to potrwać kilka minut, co sprawia, że administratorzy systemu serwera uważają, że coś jest nie tak z usługą, gdy trzeba ją ponownie uruchomić .... Mogę bez problemów po prostu upuścić całą pracę w pętli bez problemów, jednak nie mogę tego zrobić za pomocą Thread.Abort, że jest „zły”, a ponadto COM interfejs jest wywoływany, więc potrzebne jest małe czyszczenie.
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{
//This will take several minutes....
public void DoWork(){
for(int i = 0; i < 50000; i++){
//Do some work including communication with a COM interface
//Communication with COM interface doesn't take long
}
}
}
AKTUALIZACJA
Właśnie zbadana wydajność, przy użyciu znacznika cancellationToken, w którym stan isCancelled jest „badany” w kodzie, jest znacznie szybsza niż użycie waitOne na ManualResetEventSlim. Kilka szybkich figuerów, a jeśli na cancellationToken iteracja 100 000 000 razy w pętli for kosztuje mnie około. 500 ms, gdzie WaitOne kosztuje około. 3 sekundy. Tak więc wydajność w tym scenariuszu jest szybsza w użyciu cancellationToken.