private void Run() { //should we run a garbage collection thread? System.Threading.Thread gcinvoker = null; if (GCThreadInterval > 0) { gcinvoker = new System.Threading.Thread(() => { while (true) { System.Threading.Thread.Sleep(GCThreadInterval); System.GC.Collect(); } }); gcinvoker?.Start(); } var threads = new System.Collections.Generic.List <WorkerThread>(); for (int i = 0; i < Nthreads_; ++i) { var wt = new WorkerThread(this, $"WT {i}", 1234 + i); threads.Add(wt); } var hangstatus = new HangStatusGroup(Nthreads_); bool keeprunning = true; while (keeprunning) { //wait a while before asking the threads how it goes. System.Threading.Thread.Sleep(1000); //ask the threads for (int i = 0; i < Nthreads_; ++i) { hangstatus.updateThread(i, threads[i].Counter); } hangstatus.showStatus(); for (int i = 0; i < Nthreads_; ++i) { TimeSpan age = hangstatus.AgeOfUpdate(i); if (age > HangtimeLimit) { System.Console.WriteLine($"Aborting thread {i} because it appears stuck."); threads[i].Abort(); keeprunning = false; } } } //stop all threads normally System.Console.WriteLine($"stopping all threads gently..."); for (int i = 0; i < Nthreads_; ++i) { threads[i].KeepRunning = false; } //join them for (int i = 0; i < Nthreads_; ++i) { threads[i].Join(); System.Console.WriteLine($"Thread {i} has stacktrace: {threads[i].StackTrace}"); } gcinvoker?.Abort(); }
private static void Entry(WorkerThread c) { c.Doit(); }