Thinking of an answer to the question, and picking up the hook from the discussion with @Perozzo, who has already posted a solution using Thread.Abort
, I kept thinking about other ways to abort the thread, things like traffic lights for example, and I came across the interesting article of MVP Joydip Kanjilal: My two cents on the Thread.Abort and Thread.Interrupt methods
In this article, he addresses some aspects of the use of Thread.Abort()
and Thread.Interrupt()
, and recalls that in the thread we can treat this (detect that it has been aborted), using ThreadAbortException
.
In the article he also recalls that neither of the two methods is thread-safe (if you don’t know the concept, you can read more here: Thread Safety), that is, we have to treat the competition to shared resources.
The part that really caught the attention was that he, "in his opinion", did not recommend aborting the thread using Thread.Abort()
for example (in free translation):
My honest answer is that you should never use any of these
methods to close a thread. It is advisable not to use Thread.Abort methods
or Thread.Interrupt to finish one thread - you should instead of this,
take advantage of the synchronization objects (such as, Waithandles or
Traffic lights) and close "gracefully" the threads that you
are using.
Another idea he mentions is to use a variable Boolean volatile
shared with the thread, which is verified to continue the implementation of thread and may be amended by another thread, thus ending it in a "graceful" way as he mentions.
An example of the C# Programming Guide:
// variável de controle
internal volatile bool _shouldStop;
// método para "parar a thread", que vai setar a variável
public void RequestStop()
{
_shouldStop = true;
}
// método da thread
public void DoWork()
{
while (!_shouldStop)
{
Console.WriteLine("worker thread: working...");
}
Console.WriteLine("worker thread: terminating gracefully.");
}
Another way to do something similar is by using an object Cancellationtokensource . That piece of code (based In the MSDN) shows an example:
var cts = new CancellationTokenSource();
void ExecutarThread()
{
// inicia o token
cts = new CancellationTokenSource();
// Passa o token para a thread
Task.Run(() => DoWork(cts.Token), cts.Token);
}
void CancelarThread()
{
cts.Cancel();
cts.Dispose();
}
void DoWork(CancellationToken token)
{
while (alguma_condicao_de_loop)
{
// verifica se foi cancelado
if (token.IsCancellationRequested) {
Console.WriteLine("I was canceled while running.");
// sai e trata
break;
// ou dispara uma exception tratada pelo token
token.ThrowIfCancellationRequested();
}
}
}
The codes are examples adapted to demonstrate functionality, probably need some adjustment to work in each scenario, but are other ways to try to abort a thread.
In your example if your Thread generates an exception, you will never know. Most correct is to wait for the thread to finish rather than abort it.
– Gabriel Coletta
Here is a reference to how to cancel a task
– Bruno Costa