private void FailActivity(Activity activity, Exception exception, string failureMessage)
        {
            DateTimeOffset now = DateTimeOffset.Now;

            LogicalExecutionStack logicalStack = _logicalExecutionThread.Value;

            if (logicalStack == null)
            {
                throw new InvalidOperationException(ExceptionMsg_ActivityStartEndMismatch);
            }

            if (logicalStack != activity.LogicalExecutionStack)
            {
                throw new InvalidOperationException(ExceptionMsg_ActivityStacksMismatch);
            }

            var faultedActivities = new List <Activity>();

            lock (logicalStack)
            {
                Activity poppedActivity;
                do
                {
                    poppedActivity = logicalStack.Pop();
                    faultedActivities.Add(poppedActivity);
                }while (poppedActivity != activity);

                if (logicalStack.Count == 0)
                {
                    _logicalExecutionThread.Value = logicalStack.ParentStack;
                }
            }

            string faultId = Util.CreateRandomId();

            for (int i = 0; i < faultedActivities.Count; i++)
            {
                Activity    faultedActivity     = faultedActivities[i];
                IDisposable associatedOperation = faultedActivity.AssociatedOperation;

                faultedActivity.TransitionToFaulted(exception, now, failureMessage, activity, faultId);
                _pipeline.ProcessAndSend(faultedActivity);

                if (associatedOperation != null)
                {
                    var telemetry = associatedOperation as OperationTelemetry;
                    if (telemetry != null)
                    {
                        telemetry.Success = true;
                    }

                    associatedOperation.Dispose();
                }
            }
        }
        private void FailCurrentActivity(Exception exception, string failureMessage)
        {
            DateTimeOffset now = DateTimeOffset.Now;

            LogicalExecutionStack logicalStack = _logicalExecutionThread.Value;

            if (logicalStack == null)
            {
                throw new InvalidOperationException(ExceptionMsg_ActivityStartEndMismatch);
            }

            Activity activity;

            lock (logicalStack)
            {
                activity = logicalStack.Pop();

                if (logicalStack.Count == 0)
                {
                    _logicalExecutionThread.Value = logicalStack.ParentStack;
                }
            }

            IDisposable associatedOperation = activity.AssociatedOperation;

            activity.TransitionToFaulted(exception, now, failureMessage, activity, Util.CreateRandomId());
            _pipeline.ProcessAndSend(activity);

            if (associatedOperation != null)
            {
                var telemetry = associatedOperation as OperationTelemetry;
                if (telemetry != null)
                {
                    telemetry.Success = true;
                }

                associatedOperation.Dispose();
            }
        }
        public void CompleteActivity()
        {
            DateTimeOffset now = DateTimeOffset.Now;

            LogicalExecutionStack logicalStack = _logicalExecutionThread.Value;

            if (logicalStack == null)
            {
                throw new InvalidOperationException(ExceptionMsg_ActivityStartEndMismatch);
            }

            Activity activity;

            lock (logicalStack)
            {
                activity = logicalStack.Pop();

                if (logicalStack.Count == 0)
                {
                    _logicalExecutionThread.Value = logicalStack.ParentStack;
                }
            }

            IDisposable associatedOperation = activity.AssociatedOperation;

            activity.TransitionToComplete(now);
            _pipeline.ProcessAndSend(activity);

            if (associatedOperation != null)
            {
                var telemetry = associatedOperation as OperationTelemetry;
                if (telemetry != null)
                {
                    telemetry.Success = true;
                }

                associatedOperation.Dispose();
            }
        }