Waits for an action to complete
예제 #1
0
        /// <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();
            }
        }
예제 #2
0
        /// <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);
                }
            }
        }