valker's blog

valker's blog: идеи, размышления, наблюдения

Концепция REDO на C#

leave a comment »

При программировании различных задач часто возникает потребность повторить некоторые действия при ошибке. Я предлагаю вашему вниманию простой способ обобщённой реализации такой функциональности:

    1 namespace Utilities

    2 {

    3     public delegate void CommandDelegate();

    4 

    5     public interface IExecutor {

    6         void executeCommand(CommandDelegate cmd);

    7     }

    8 }

    1 using System;

    2 

    3 namespace Utilities {

    4     public class RepeatExecutor : IExecutor {

    5         private int attempts_;

    6         private Type[] exceptions_;

    7         private bool status_;

    8         private Exception ex_;

    9 

   10         public RepeatExecutor(int attempts,

   11                               Type[] exceptions) {

   12             attempts_ = attempts;

   13             exceptions_ = exceptions;

   14             status_ = false;

   15         }

   16 

   17         public bool Status {

   18             get { return status_; }

   19         }

   20 

   21         public Exception Except {

   22             get { return ex_; }

   23         }

   24 

   25         public bool executeCommandAndGetStatus(

   26                 CommandDelegate cmd) {

   27             executeCommand(cmd);

   28             return Status;

   29         }

   30 

   31         public void executeCommand(CommandDelegate cmd) {

   32             int attempt = attempts_;

   33             do {

   34                 try {

   35                     cmd();

   36                     status_ = true;

   37                 } catch (Exception e) {

   38                     Type et = e.GetType();

   39                     bool found = false;

   40                     foreach (Type t in exceptions_) {

   41                         if (et.Equals(t)

   42                             || et.IsSubclassOf(t)) {

   43                             found = true;

   44                             break;

   45                         }

   46                     }

   47                     if (!found) {

   48                         throw;

   49                     } else {

   50                         ex_ = e;

   51                         status_ = false;

   52                     }

   53                 }

   54             } while (!status_ && (—attempt > 0));

   55         }

   56     }

   57 }

Пример использования:

  278 private void repeat(CommandDelegate cmd, string message) {

  279     Type[] types = new Type[] {typeof (LayerException)};

  280     RepeatExecutor executor =

  281             new RepeatExecutor(REPEAT_ATTEMPTS,

  282                                types);

  283     if (!executor.executeCommandAndGetStatus(cmd)) {

  284         throw new ReprogrammingException(

  285                 message

  286                 + ‘(‘ + executor.Except.Message + ‘)’);

  287     }

  288 }

Надеюсь, этот приём будет вам полезен в вашей работе.

Written by valker

Ноябрь 24, 2006 в 9:55 дп

Опубликовано в жизнь

Добавить комментарий

Please log in using one of these methods to post your comment:

Логотип WordPress.com

Для комментария используется ваша учётная запись WordPress.com. Выход / Изменить )

Фотография Twitter

Для комментария используется ваша учётная запись Twitter. Выход / Изменить )

Фотография Facebook

Для комментария используется ваша учётная запись Facebook. Выход / Изменить )

Google+ photo

Для комментария используется ваша учётная запись Google+. Выход / Изменить )

Connecting to %s

%d такие блоггеры, как: