public static void ProcessUndo <TStepId, TData>(RunUndoContext <TStepId, TData> context)
public static async Task ProcessUndo <TStepId, TData>(RunUndoContext <TStepId, TData> context) #endif { ITransactionStep <TStepId, TData> currentStep = context.Session.StepEnumerator.CurrentStep; ITransactionSession <TStepId, TData> session = context.Session; Stopwatch watch = new Stopwatch(); try { watch.Start(); #if NET35 || NOASYNC currentStep.UndoAction(session.StepEnumerator.Data, session); #else if (currentStep.UndoAction != null) { currentStep.UndoAction(session.StepEnumerator.Data, session); } else { await currentStep.AsyncUndoAction(session.StepEnumerator.Data, session); } #endif watch.Stop(); #if NET35 || NOASYNC context.Session.TransactionContext.SessionStorage.StepReceding(session); #else await context.Session.TransactionContext.SessionStorage.StepReceding(session); #endif if (session.ShouldLogStepExecution()) { session.TransactionContext .Logger .LogExecutionTime( watch.Elapsed, "Transaction '{0}': execution time for undo step action for step '{1}' with id '{2}'.", session.TransactionContext.Info.Name, session.StepEnumerator.CurrentStepIndex, currentStep.Id); } } catch (Exception e) { watch.Stop(); string info = string.Format( "Transaction '{0}': an error occurred during processing undo step action for step '{1}' with id '{2}', execution time '{3}'.", session.TransactionContext.Info.Name, session.StepEnumerator.CurrentStepIndex, currentStep.Id, watch.Elapsed); session.TransactionContext.Logger.ErrorFormat(e, info); #if NET35 || NOASYNC SessionEndPreparationOperation.PrepareEndSession(new SessionEndContext <TStepId, TData>() #else await SessionEndPreparationOperation.PrepareEndSession(new SessionEndContext <TStepId, TData>() #endif { Session = context.Session, RunPostActions = false, Result = ResultType.Failed } .AddError(context.CaughtException) .AddError(e)); } }
public static async Task RunUndo <TStepId, TData>(RunUndoContext <TStepId, TData> context) #endif { while (context.ProcessStepPredicate(context.Session.StepEnumerator.CurrentStep)) { ITransactionStep <TStepId, TData> step = context.Session.StepEnumerator.CurrentStep; if (step == null) { if (context.NoSessionEnd) { #if NET35 || NOASYNC context.UndoFinishAction(); #else await context.UndoFinishAction(); #endif return; } #if NET35 || NOASYNC SessionEndPreparationOperation.PrepareEndSession(new SessionEndContext <TStepId, TData>() #else await SessionEndPreparationOperation.PrepareEndSession(new SessionEndContext <TStepId, TData>() #endif { RunPostActions = false, Session = context.Session, Result = context.Result } .AddError(context.CaughtException)); return; } ITransactionSession <TStepId, TData> session = context.Session; if (session.Recovered && step.Settings.NotRunOnRecovered()) { session.TransactionContext .Logger .DebugFormat( "Transaction '{0}': ignoring the undo step action for step '{1}' with id '{2}' as the step cannot be executed on a recovered transaction.", session.TransactionContext.Info.Name, session.StepEnumerator.CurrentStepIndex, session.StepEnumerator.CurrentStep.Id); session.StepEnumerator.MovePrevious(); continue; } #if NET35 || NOASYNC if (step.UndoAction == null) #else if (step.UndoAction == null && step.AsyncUndoAction == null) #endif { session.TransactionContext .Logger .DebugFormat( "Transaction '{0}': no undo step action for step '{1}' with id '{2}'.", session.TransactionContext.Info.Name, session.StepEnumerator.CurrentStepIndex, session.StepEnumerator.CurrentStep.Id); session.StepEnumerator.MovePrevious(); continue; } IExecutor executor = step.UndoActionExecutor != null ? step.UndoActionExecutor : step.Settings.SameExecutorForAllActions() ? step.StepActionExecutor : null; if (executor != null && executor.ShouldRun) { #if NET35 || NOASYNC executor.Run(() => { ProcessUndoOperation.ProcessUndo(context); if (!session.Ended) { session.StepEnumerator.MovePrevious(); RunUndoOperation.RunUndo(context); } }); #else executor.Run(async() => { await ProcessUndoOperation.ProcessUndo(context); if (!session.Ended) { session.StepEnumerator.MovePrevious(); await RunUndoOperation.RunUndo(context); } }); #endif return; } else { #if NET35 || NOASYNC ProcessUndoOperation.ProcessUndo(context); #else await ProcessUndoOperation.ProcessUndo(context); #endif session.StepEnumerator.MovePrevious(); } } #if NET35 || NOASYNC context.UndoFinishAction(); #else await context.UndoFinishAction(); #endif }