Остановка дочерних потоков - 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!");
}