Остановка дочерних потоков - C#

Узнай цену своей работы

Формулировка задачи:

Основная программа запускает 2 потока для определенных вычислений, при этом сама запускает таймер на 10 сек и ждет результатов работы потоков. Если спустя 10 сек потоки не прекращают работать (зациклились?), нужно остановить потоки и спросить пользователя - прекратить или продолжить работу. Вопрос. Как остановить эти потоки с возможностью перезапуска? Условие такое что сами потоки только делают вычисления, они не должны обрабатывать никакие другие запросы, в том числе на прекращение или приостановку выполнения (обязательное искусственное условие).

Решение задачи: «Остановка дочерних потоков»

textual
Листинг программы
AutoResetEvent awaiter = new AutoResetEvent(false);
AutoResetEvent checker = new AutoResetEvent(false);
 
void SuperJob()
{
    long i = 0;
    while (i < 1L*2000*1000*1000)
    {
        i++;
        if (i % (300L*1000*1000) == 0L)
            Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
    }
    Console.WriteLine("Completed: " + Thread.CurrentThread.ManagedThreadId);
}
 
void Main()
{
    Thread[] threads = Enumerable.Range(0, 2).Select(i => new Thread(SuperJob)).ToArray();
    Console.WriteLine("Computing has started!");
    Array.ForEach(threads, t => t.Start());
    int period = 10000;
    var timer = new System.Threading.Timer(t => awaiter.Set(), null, period, period);
    var checkCompletionTimer = new System.Threading.Timer(t => checker.Set(), null, 100, 100);
    while (true)
    {
        int timerNumber = WaitHandle.WaitAny(new WaitHandle[] { awaiter, checker });
        if (timerNumber == 1)   
            if (threads.All(t => !t.IsAlive))
                break;
            else
                continue;
        timer.Change(Timeout.Infinite, period);
        checkCompletionTimer.Change(Timeout.Infinite, period);
        Console.WriteLine("Suspend computing? (Y/N)");
        if (Console.ReadLine() == "Y")
        {
            int exceptions = 0;
            Array.ForEach(threads, t =>
            {
                try 
                { 
                    t.Suspend();
                }
                catch (ThreadStateException)
                {
                    exceptions++;
                }
            });
            if (exceptions == threads.Length)
                break;
            Console.WriteLine("Computing successfully suspended! Press enter to continue computing!");
            Console.ReadLine();
 
            Array.ForEach(threads, t =>
            {
                try
                {
                    t.Resume();
                }
                catch (ThreadStateException) { }
            });
            Console.WriteLine("Computing has continued!");
        }
        timer.Change(period, period);
        checkCompletionTimer.Change(100, 100);
    }
    Console.WriteLine("Computing completed!");
}

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

15   голосов , оценка 3.933 из 5
Похожие ответы