/// <summary> /// Kills all currently running/pending tasks. /// Releases all resources. /// </summary> public void Dispose() { lock (this) { if (!disposed) { startInitialThreads.Wait(); disposed = true; ShutdownPool.Set(); //ts.Cancel(); // n.b. should not timeout, but you can't be too careful. lock (RunningJobs) { Thread t = new Thread(() => { // n.b. cannot WaitAll on STA thread WaitHandle.WaitAll(RunningJobs.ToArray(), 30 * 1000); }); t.SetApartmentState(ApartmentState.MTA); t.Start(); t.Join(); } ShutdownPool.Dispose(); startInitialThreads.Dispose(); } } }