public override void OnActionExecuted(ExecutionContext context)
            {
#if TRACK_DETAILED_STATS
                if (StatisticsCollector.CollectTurnsStats)
                {
                    if (agent.GetWorkItemState(context).ItemType != WorkItemType.WorkItemGroup)
                    {
                        SchedulerStatisticsGroup.OnTurnExecutionEnd(Utils.Since(context.WorkItem.ExecutionStart));
                    }
                }
#endif
            }
            public override bool ExceptionHandler(Exception ex, ExecutionContext context)
            {
                if (ex is ThreadAbortException)
                {
                    if (log.IsEnabled(LogLevel.Debug))
                    {
                        log.Debug("Received thread abort exception - exiting. {0}.", ex);
                    }
                    Thread.ResetAbort();
                }
                else
                {
                    log.Error(ErrorCode.Runtime_Error_100031, "Exception bubbled up to worker thread", ex);
                }

                context.CancellationTokenSource.Cancel();
                return(true);
            }
            private void TrackWorkItemDequeue(ExecutionContext context)
            {
#if TRACK_DETAILED_STATS
                var todo = agent.GetWorkItemState(context);
                if (todo.ItemType != WorkItemType.WorkItemGroup)
                {
                    if (StatisticsCollector.CollectTurnsStats)
                    {
                        SchedulerStatisticsGroup.OnThreadStartsTurnExecution(context.ThreadIndex, todo.SchedulingContext);
                    }
                }

                if (StatisticsCollector.CollectGlobalShedulerStats)
                {
                    SchedulerStatisticsGroup.OnWorkItemDequeue();
                }
#endif
            }
            public override bool ExceptionHandler(Exception ex, ExecutionContext context)
            {
                if (ex is ThreadAbortException tae)
                {
                    // The current turn was aborted (indicated by the exception state being set to true).
                    // In this case, we just reset the abort so that life continues. No need to do anything else.
                    if (tae.ExceptionState != null && tae.ExceptionState.Equals(true))
                    {
                        Thread.ResetAbort();
                    }
                    else if (!context.CancellationTokenSource.IsCancellationRequested)
                    {
                        log.Error(ErrorCode.Runtime_Error_100029, "Caught thread abort exception, allowing it to propagate outwards.", ex);
                    }
                }
                else
                {
                    log.Error(ErrorCode.Runtime_Error_100030,
                              string.Format("Thread caught an exception thrown from task {0}", context.WorkItem.State), ex);
                }

                return(true);
            }
 public override void OnActionExecuting(ExecutionContext context)
 {
     TrackWorkItemDequeue(context);
 }