Home > OS >  Stop C# thread immediately without "Thread.Abort()"
Stop C# thread immediately without "Thread.Abort()"

Time:11-05

public class Worker
{
    private CancellationTokenSource cts;
    private Thread t;

    public Worker()
    {
        cts = new CancellationTokenSource();
        t = new Thread(() => { ThreadTask(cts.Token); });
    }

    ~Worker()
    {
        cts.Dispose();
    }

    private void ThreadTask(CancellationToken ct)
    {
        try
        {
            while (true)
            {
                if (ct.IsCancellationRequested)
                {
                    Debug.WriteLine("Cancelllation requested");
                    break;
                }

                // long task 1
                Debug.WriteLine("Task 1 completed");
                Thread.Sleep(2000);
                // long task 2
                Debug.WriteLine("Task 2 completed");
                Thread.Sleep(2000);
                // long task 3
                Debug.WriteLine("Task 3 completed");
                Thread.Sleep(2000);
                // long task 4
                Debug.WriteLine("Task 4 completed");
                Thread.Sleep(2000);
                Debug.WriteLine("All tasks completed");
            }
        }
        catch (Exception ex)
        {
            Debug.WriteLine("Thread exception: "   ex.ToString());
        }
        finally
        {
            // cleanup
            Debug.WriteLine("Thread cleanup");
        }
    }

    public void Start()
    {
        t.Start();
    }

    public void Stop()
    {
        cts.Cancel();
    }
}

I would like to know if it is possible to interrupt a thread before it finishes executing.

For example, in code described above, when calling a function Stop(), the thread will be stopped when it finishes execution, I would like to stop it more quickly, such as between "long tasks" or even while a Thread.Sleep(2000).

A solution would be to maybe throw an exception in the task thread when calling the Stop() like Thread.Abort(), but Thread.Abort() does not work on Net 6.0, how can I do that?

Environment:

  • C#
  • Net 6.0
  • Windows 10 x64
  • Visual Studio 2019 and Visual Studio 2022

CodePudding user response:

You could use the Thread.Interrupt method. This API is supported in the current .NET platform.

Interrupts a thread that is in the WaitSleepJoin thread state.

If this thread is not currently blocked in a wait, sleep, or join state, it will be interrupted when it next begins to block.

ThreadInterruptedException is thrown in the interrupted thread, but not until the thread blocks. If the thread never blocks, the exception is never thrown, and thus the thread might complete without ever being interrupted.

You'll have to handle a possible ThreadInterruptedException inside the body of the ThreadStart delegate, otherwise the process may crash when the Interrupt is invoked. Or you could just handle all exceptions with a generic catch (Exception) handler, as you are currently doing.

  • Related