Parando um Thread, ManualResetEvent, boolean volátil ou cancellationToken

Eu tenho um thread (STAThread) em um serviço do Windows, que executa uma grande quantidade de trabalho. Quando o serviço do windows é reiniciado eu quero parar este segmento normalmente.

Eu sei de algumas maneiras

Um booleano volátilManualResetEventCancelamentoToken

Tanto quanto eu descobri Thread.Abort é um não ir ...

Qual é a melhor prática? O trabalho é executado em outra classe diferente daquela em que o encadeamento é iniciado, portanto, é necessário introduzir um parâmetro cancellationToken em um construtor ou, por exemplo, ter uma variável volátil. Mas eu simplesmente não consigo descobrir o que é mais inteligente.

Atualizar
Só para esclarecer um pouco, encerrei um exemplo muito simples do que estou falando. Como dito anteriormente, isso está sendo feito em um serviço do Windows. No momento, estou pensando em um booleano volátil que é verificado no loop ou em um CancellationToken .... Eu não posso esperar que o loop termine, conforme indicado abaixo, isso pode levar vários minutos, fazendo com que os administradores do servidor acreditem que algo está errado com o serviço quando eles precisam para reiniciá-lo .... eu posso sem problemas apenas soltar todo o trabalho dentro do loop sem problemas, no entanto eu não posso fazer isso com um Thread.Abort é "mal" e, além disso, um COM interface é chamada, então é necessária uma pequena limpeza.

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
    }
  }
}

ATUALIZAR
Apenas examinei o desempenho, usando um cancelamentoToken onde o estado isCancelled é "examinado" no código, é muito mais rápido do que usar um waitOne em um ManualResetEventSlim. Alguns resultados rápidos, e se o cancelamentoThere iterating 100.000.000 vezes em loop for me custa aprox. 500 ms, onde o WaitOne custa aprox. 3 segundos. Portanto, desempenho nesse cenário é mais rápido usar o cancelamentoToken.

questionAnswers(4)

yourAnswerToTheQuestion