0

How interrupt thread child in this case? I need interrupt foreach in thread child after throw exception in thread parent

            Thread child;

            Thread parent = new Thread(() =>            
            {

                child = new Thread(() =>
                {
                    for (int i = 0; i < int.MaxValue; i++)
                    {
                        Console.WriteLine("THREAD 1 = " + i);
                    }
                });

                child.Start();

                try
                {
                    child.Join();
                }
                catch (Exception ex)
                {
                    System.Console.WriteLine(ex.ToString());

**                    // here????**

                }
            });

            parent.Start();

            parent.Interrupt();

Interrupt thread child

  • 2
    What are you trying to do? There's never any good reason to interrupt or abort a thread. In fact, there's seldom any reason to use threads directly since .NET Framework 4.5. Tasks, async/await, Parallel.ForEach etc. make multithreaded programming a lot easier. – Panagiotis Kanavos Dec 19 '22 at 14:48
  • 2
    Even when using threads, signaling is done through synchronization primitives like AutoResetEvent, ManualResetEvent etc, not by throwing exceptions – Panagiotis Kanavos Dec 19 '22 at 14:50
  • Poor mans solution. Set a variable in your catch block. Let the child Thread check that variable and if set it can end itself gracefully. – Ralf Dec 19 '22 at 15:00
  • 1
    @Ralf that won't work without a synchronization primitive like an AutoResetEvent. That's how things worked before .NET. In all current .NET versions though, a CancellationTokenSource is both easier and safer to use – Panagiotis Kanavos Dec 19 '22 at 15:03
  • Interruption strongly implies pause-and-continue. So, i read your question as you wanting to continue the interrupted thread(s) at a later time after interruption. Is that correct? –  Dec 19 '22 at 15:24
  • In my case i would like to stop thread child when stopped thread parent. Its a test because in my project c# the for (Console.WriteLine("THREAD 1 = " + i)) is not know (function another lib), that's why i dont used a cancellation token. – José Robson Assis Dec 26 '22 at 16:39

2 Answers2

3

You cannot "interput" threads. Older .Net versions had Thread.Abort, but there are several good reasons why it should never be used.

What you should do is ask the thread to stop processing, and your thread should frequently check if needs to stop.

There are several ways to do this, one example would be the cancellation token. Let your thread take a cancellation token as input and in your loop add a call to

myCancellationToken.ThrowIfCancellationRequested();

Your caller would create a cancellation token source to generate the token and call .Cancel() to request the thread to abort.

However, using threads directly is very outdated, you should be using task based programming. There are common patterns to do most common tasks in a elegant and compact way, like DataFlow, Parallel.For, PLinq, concurrent collections etc.

Multi threaded programming is difficult. You need to have a fair bit of knowledge on the topic before you try to write anything intended for real world use. Thread safety bugs are quite easy to make, and are notoriously difficult to find and debug. So I would recommend studying thread safety, as well as modern threading patterns. This is not an area where trial and error is appropriate, since you are likely to create thing that work 99.9% of the time, or works 100% on your computer, but not in production.

JonasH
  • 28,608
  • 2
  • 10
  • 23
  • In my case i would like to stop thread child when stopped thread parent. Its a test because in my project c# the for (Console.WriteLine("THREAD 1 = " + i)) is not know (function another lib), that's why i dont used a cancellation token. – José Robson Assis Dec 26 '22 at 16:40
  • @JoséRobsonAssis You can only stop threads cooperatively. If your calling a function in another library you either need to a) find a method with cancellation support, b) wait for the method to complete, c) run the method in a separate process and kill the process, d) Let the method continue in the background, but stop waiting for it to complete. – JonasH Jan 02 '23 at 18:26
0

JonasH's answer is a good one, but just for reference, here's how to use the CancellationToken with the original code:

CancellationTokenSource cts = new CancellationTokenSource();
CancellationToken ct = cts.Token;

Thread parent = new Thread(() =>
{

    Thread child = new Thread(() =>
    {
        for (int i = 0; i < int.MaxValue; i++)
        {
            if (ct.IsCancellationRequested)
            {
                break;
            }
            Console.WriteLine("THREAD 1 = " + i);
        }
    });

    child.Start();

    try
    {
        child.Join();
    }
    catch (Exception ex)
    {
        System.Console.WriteLine(ex.ToString());
        cts.Cancel();
    }
});

parent.Start();
parent.Interrupt();
Enigmativity
  • 113,464
  • 11
  • 89
  • 172
  • In my case i would like to stop thread child when stopped thread parent. Its a test because in my project c# the for (Console.WriteLine("THREAD 1 = " + i)) is not know (function another lib), that's why i dont used a cancellation token. – José Robson Assis Dec 26 '22 at 16:40
  • @JoséRobsonAssis - I'm sorry, but you're going to have to explain that comment in more detail. – Enigmativity Dec 26 '22 at 21:59