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ść logicznaManualResetEventCancellationToken

O 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.

questionAnswers(4)

yourAnswerToTheQuestion