Which is the best way to add a retry/rollback mechanism for sync/async tasks in C#?

后端 未结 5 889
后悔当初
后悔当初 2021-02-04 01:15

Imagine of a WebForms application where there is a main method named CreateAll(). I can describe the process of the method tasks step by step as follows:

1) Stores to da

5条回答
  •  [愿得一人]
    2021-02-04 01:58

    You can opt for Command pattern where each command contains all the necessary information like connection string, service url, retry count etc.On top of this, you can consider rx, data flow blocks to do the plumbing.

    High level view:

    Update: Intention is to have Separation Of Concern. Retry logic is confined to one class which is a wrapper to existing command. You can do more analysis and come up with proper command, invoker and receiver objects and add rollback functionality.

    public abstract class BaseCommand
    {
        public abstract RxObservables Execute();
    }
    
    public class DBCommand : BaseCommand
    {
        public override RxObservables Execute()
        {
            return new RxObservables();
        }
    }
    
    public class WebServiceCommand : BaseCommand
    {
        public override RxObservables Execute()
        {
            return new RxObservables();
        }
    }
    
    public class ReTryCommand : BaseCommand // Decorator to existing db/web command
    {
        private readonly BaseCommand _baseCommand;
        public RetryCommand(BaseCommand baseCommand)
        {
             _baseCommand = baseCommand
        }
        public override RxObservables Execute()
        {
            try
            {
                //retry using Polly or Custom
                return _baseCommand.Execute();
            }
            catch (Exception)
            {
                throw;
            }
        }
    }
    
    public class TaskDispatcher
    {
        private readonly BaseCommand _baseCommand;
        public TaskDispatcher(BaseCommand baseCommand)
        {
            _baseCommand = baseCommand;
        }
    
        public RxObservables ExecuteTask()
        {
            return _baseCommand.Execute();
        }
    }
    
    public class Orchestrator
    {
        public void Orchestrate()
        {
            var taskDispatcherForDb = new TaskDispatcher(new ReTryCommand(new DBCommand));
            var taskDispatcherForWeb = new TaskDispatcher(new ReTryCommand(new WebCommand));
            var dbResultStream = taskDispatcherForDb.ExecuteTask();
            var WebResultStream = taskDispatcherForDb.ExecuteTask();
        }
    }
    

提交回复
热议问题