/// <summary>
 /// Determines whether the specified calculation is cancelling.
 /// </summary>
 /// <param name="calculationId">The calculation identifier.</param>
 /// <returns>
 ///   <c>true</c> if the specified calculation identifier is cancelling; otherwise, <c>false</c>.
 /// </returns>
 public bool IsCancelling(int calculationId)
 {
     return(calculationDepot.HasState(calculationId, State.NameCancelling));
 }
예제 #2
0
        /// <summary>
        /// Dispatches a calculation and sets its state to running.
        /// </summary>
        /// <param name="circleChunkSize">Size of the circle chunk.</param>
        public void Dispatch(int circleChunkSize)
        {
            var calculation     = calculationService.GetFirstByState(State.NameEnqueued);
            var stateCancelling = stateDepot.GetByName(State.NameCancelling);

            Timer cancellingTimer       = null;
            CancellationTokenSource cts = new CancellationTokenSource();

            try
            {
                if (calculation == null)
                {
                    return;
                }

                var runningCalculation = calculationService.GetFirstByState(State.NameRunning);

                if (runningCalculation != null)
                {
                    App.Logger.Info($"Calculation with state {State.NameEnqueued} found but already a calculation in state {State.NameRunning}.");
                    return;
                }

                cancellingTimer = new Timer((t) =>
                {
                    if (calculationDepotTimer.HasState(calculation.Id, State.NameCancelling))
                    {
                        // Cancel Task and stop timer
                        cts.Cancel();
                        cancellingTimer.Dispose();
                    }
                }, null, App.Config.CancellationCheckInterval, App.Config.CancellationCheckInterval);

                DispatchCalculation(calculation, cts.Token, circleChunkSize);
            }
            catch (AggregateException ex)
            {
                // Parallel Loop throws Aggregate Exception
                if (ex.InnerExceptions.Any(x => x is OperationCanceledException))
                {
                    Cancel(calculation);
                }
            }
            catch (OperationCanceledException)
            {
                Cancel(calculation);
            }
            catch (Exception)
            {
                var stateError = stateDepot.GetByName(State.NameError);
                calculation.StateId = stateError.Id;

                throw;
            }
            finally
            {
                if (calculation != null)
                {
                    calculation.EndDate = DateTime.Now;
                    calculationDepot.Save(calculation);
                }

                if (cancellingTimer != null)
                {
                    cancellingTimer.Dispose();
                }
            }
        }