c# – Terminating a thread from another thread

Question:

For example, there are several almost identical streams that can last indefinitely.

initialization:

 ParameterizedThreadStart pts = new ParameterizedThreadStart(runMethod);
 Thread t = new Thread(pts);            
 t.Start(values);

flow:

 void run(object p)
 {
      // нужен поток, который повторяет одно и то же с некоторой переодичностью, поэтому так:

      while(true)
      {
           // что-то делаем
           doAnything(p);

           Thread.Sleep(60000);
      }
 }

The question is how to interrupt them adequately? It would be great if they could be interrupted while they are sleeping, or at least after doAnything ();

it is possible in the main thread to do something like

 Thread t = new Thread(pts);            
 t.Start(values);
 ...
 t.Abort();

but I'm not sure that some important operation will not be interrupted in the stream – loading / deleting / processing a file or some transaction will not commit

Answer:

This is done most beautifully through the CancellationToken mechanism. This mechanism is specifically designed to pass stop and cancel messages between threads:

void run(object p)
{
  var ct = (CancellationToken)p;

  do
  {
       // что-то делаем
       doAnything(p);
  } while (!ct.IsCancellationRequested && !ct.WaitHandle.WaitOne(60000));
}

Here I am using waiting on an event as an interruptible alternative to Thread.Sleep . If the wait is successful, then the thread must be stopped. If it is unsuccessful (waiting timeout), then you can continue to work.

Before waiting, I check IsCancellationRequested to not IsCancellationRequested kernel event when not required.

Creating a stream like this:

using (var cts = new CancellationTokenSource()) {
    new Thread(run).Start(cts.Token);
    ...
    cts.Cancel();
}

You can also use a task ( Task.Run ) instead of a thread. In this case, it is better to use Task.Delay for waiting, this will allow you to do without kernel objects at all:

async Task run(CancellationToken ct)
{
  do
  {
       // что-то делаем
       doAnything(p);

       await Task.Delay(60000, ct);
  } while (!ct.IsCancellationRequested);
}

Task.Run(() => run(cts.Token));

A bonus to using CancellationToken is the ability to pass ct further to doAnything – thanks to which you can finely choose at what moments an interruption of processing is allowed.

If you use the asynchronous option, then almost all the asynchronous functions of the standard library can also accept a CancellationToken , which allows you to safely interrupt any long operation if you wish.


In older runtimes where there is no CancellationToken mechanism,ManualResetEvent can be used for the same purpose. The principle is the same – instead of calling Thread.Sleep wait on the event and check the result.

Scroll to Top