/// <summary> /// Stops the specified primary worker /// </summary> /// <param name="worker">The worker.</param> public void StopPrimary(IPrimaryWorker worker) { Guard.NotNull(() => worker, worker); _waitForEventOrCancel.Set(); _waitForEventOrCancel.Cancel(); //stop is a blocking operation for the primary worker Task.Run(worker.Stop); //wait for workers to stop WaitForDelegate.Wait(() => worker.Running, _configuration.TimeToWaitForWorkersToStop); if (worker.Running) { worker.AttemptToTerminate(); } //attempt to cancel workers if any are still running if (worker.Running) { _cancelWorkSource.CancellationTokenSource.Cancel(); WaitForDelegate.Wait(() => worker.Running, _configuration.TimeToWaitForWorkersToCancel); if (worker.Running) { worker.AttemptToTerminate(); } } //force kill workers that are still running by aborting the thread, or waiting until work has completed if (worker.Running) { worker.TryForceTerminate(); } }
/// <summary> /// Stops the specified workers. /// </summary> /// <param name="workers">The workers.</param> public void Stop(List <IWorker> workers) { Guard.NotNull(() => workers, workers); _waitForEventOrCancel.Set(); _waitForEventOrCancel.Cancel(); if (workers.Count == 0) { return; } //wait for workers to stop WaitForDelegate.Wait(() => workers.Any(r => r.Running), _configuration.TimeToWaitForWorkersToStop); if (workers.Any(r => r.Running)) { workers.AsParallel().ForAll(w => w.AttemptToTerminate()); } var alCancel = workers.Where(worker => worker.Running).ToList(); //attempt to cancel workers if any are still running if (alCancel.Count > 0) { _cancelWorkSource.CancellationTokenSource.Cancel(); WaitForDelegate.Wait(() => alCancel.Any(r => r.Running), _configuration.TimeToWaitForWorkersToCancel); if (alCancel.Any(r => r.Running)) { alCancel.AsParallel().ForAll(w => w.AttemptToTerminate()); } } //force kill workers that are still running by aborting the thread, or waiting until work has completed var alForceTerminate = workers.Where(worker => worker.Running).ToList(); if (alForceTerminate.Count > 0) { alForceTerminate.AsParallel().ForAll(w => w.TryForceTerminate()); } //dispose workers - they are created by a factory, and must be disposed of foreach (var worker in workers) { try { worker.Dispose(); } catch (Exception e) { _log.ErrorException("An error has occurred while disposing of a worker", e, null); } } }