Search code examples
c#multithreadingsleepresumepause

Pause/resume a thread in C#


I try to pause all my threads when I reach a certain value but I can't do it.

I would like that when I reach this value all threads are paused for 10 seconds and after these 10 seconds all threads start again.

I tried that with : Threads.Sleep(); | Threads.Interrupt(); and Threads.Abort(); but nothing work.

I tried what you can see in the code below.

        static void Main(string[] args)
        {
            for (int i = 0; i < 10; i++)
            {
                Threads.Add(new Thread(new ThreadStart(example)));
                Threads[i].Start();
            }

            for (int i = 0; i < Threads.Count; i++)
                Threads[i].Join();
        }

        static void example()
        {           
            while (true)
            {
                Console.WriteLine(value++);
                checkValue();
            }
        }
        public static void checkValue()
        {
            if (value% 1000 == 0 && value!= 0)
            {
                for (int i = 0; i < Threads.Count; i++)
                    Threads[i].Interrupt();

                Thread.Sleep(1000);

                for (int i = 0; i < Threads.Count; i++)
                    Threads[i].Resume();
            }
        }

Solution

  • Here is an example of pausing some threads cooperatively, by using the PauseTokenSource + PauseToken pair from Stephen Cleary's AsyncEx.Coordination package. This example shows also the use of the analogous CancellationTokenSource + CancellationToken pair, that inspired the creation of the aforementioned pausing mechanism.

    var pts = new PauseTokenSource() { IsPaused = true };
    var cts = new CancellationTokenSource();
    int value = 0;
    
    // Create five threads
    Thread[] threads = Enumerable.Range(1, 5).Select(i => new Thread(() =>
    {
        try
        {
            while (true)
            {
                cts.Token.ThrowIfCancellationRequested(); // self explanatory
                pts.Token.WaitWhilePaused(cts.Token); // ...and don't wait if not paused
                int localValue = Interlocked.Increment(ref value);
                Console.WriteLine($"Thread #{i}, Value: {localValue}");
            }
        }
        catch (OperationCanceledException) // this exception is expected and benign
        {
            Console.WriteLine($"Thread #{i} Canceled");
        }
    })).ToArray();
    
    // Start the threads
    foreach (var thread in threads) thread.Start();
    
    // Now lets pause and unpause the threads periodically some times
    // We use the main thread (the current thread) as the controller
    Thread.Sleep(500);
    pts.IsPaused = false;
    Thread.Sleep(1000);
    pts.IsPaused = true;
    Thread.Sleep(1000);
    pts.IsPaused = false;
    Thread.Sleep(1000);
    pts.IsPaused = true;
    Thread.Sleep(500);
    
    // Finally cancel the threads and wait them to finish
    cts.Cancel();
    foreach (var thread in threads) thread.Join();
    

    You may need to read this first, to get a grasp on the model used by the .NET platform for cooperative cancellation. Cooperative "pausation" is very similar.