Search code examples
c#multithreadingtokenthreadpool

Cannot stop properly all threads in c#


I'm trying in c# to stop all threads with token or thread.abort, but both don't work properly

                int workerThreads = 1;
                int portThreads = 0;

                ThreadPool.SetMinThreads(workerThreads, portThreads);
                ThreadPool.SetMaxThreads(workerThreads,portThreads);
                foreach (string d in list)
                {
                    var p = d;
                    ThreadPool.QueueUserWorkItem((c) =>
                    {
                        this.checker(p,cts.Token);
                    });
                }`

The function called with checker is built as follow:

    private void checker(string f, object obj)
    {
        try
        {
            CancellationToken token = (CancellationToken)obj;

            if (token.IsCancellationRequested)
            {
                MessageBox.Show("Stopped", "Checker aborted");
                token.ThrowIfCancellationRequested();
                cts = new CancellationTokenSource();
            } //etc main features of fucntion are hidden from here

I want to stop properly all threads when i call the cts.Cancel(); but every time appears: Stopped , checker aborted and not only for one time but maybe it is shown for every thread process. How can i show the message one time and stopping all threads in the same moment? I want also set a number of maximum threads that should work before to proceed with Others. I tried with SetMaxThreads but neither this seems to work.


Solution

  • Please refer to the comments for the best practice advises, because what you are doing here is not completely correct, but to achieve your goal you can use a flag combined with lock like this:

    private static object _lock = new object();
    private static bool _stoppedNotificationShown = false;
    private void checker(string f, object obj)
    {
        try
        {
            CancellationToken token = (CancellationToken)obj;
    
            if (token.IsCancellationRequested)
            {
                lock(_lock) {
                    if (!_stoppedNotificationShown) {
                        _stoppedNotificationShown = true;
                        MessageBox.Show("Stopped", "Checker aborted");
                    }
                }
                token.ThrowIfCancellationRequested();
                cts = new CancellationTokenSource();
            } //etc main features of fucntion are hidden from here