У меня могут быть сильная безопасность исключения и события?

Команде r может предшествовать ноль или один адрес.

Из документации sed :

Sed Addresses

Адрес не требуется, но если указан, должен быть числом (которое подсчитывает входные строки в совокупности во входных файлах), символом доллара ('), который относится к последней строке ввода, или адресом контекста (который состоит из регулярного выражения, перед которым следует разделитель, а за которым следует разделитель). [ 1127] blockquote>

В ваших примерах не используется число или $ в качестве спецификатора адреса. Единственная оставшаяся опция - это регулярное выражение, заключенное в разделители. Разделителем по умолчанию для regex в sed является косая черта (/).

Поскольку / является разделителем regex, любое использование / внутри regex необходимо избегать (т. Е. Ему предшествует \).
Команда, которая вам нужна:

sed -i '/\/def\/ghi\/jkl/ r numbers' letters2

Чтобы использовать другой разделитель для регулярного выражения (чтобы избежать необходимости избегать прямой косой черты), вы должны ставить перед ним обратную косую черту, когда он используется в качестве открытого разделителя. (до адреса). Не избегайте его, когда он используется после regex. Выход из него внутри regex говорит sed использовать его буквальное значение.

Команда в этом случае:

sed -i '\@/def/ghi/jkl@ r numbers' letters2

Пример, который вы утверждаете, работает (sed -i "def r numbers" letters), не следует этому шаблону и фактически не работает (по крайней мере, на macOS sed я использую).
Это должно быть sed -i "/def/ r numbers" letters или, если быть более точным, sed -i "/^def$/ r numbers" letters.

), который относится к последней строке ввода, или адресом контекста (который состоит из регулярного выражения, перед которым следует разделитель, а за которым следует разделитель). [ 1127] blockquote>

В ваших примерах не используется число или $ в качестве спецификатора адреса. Единственная оставшаяся опция - это регулярное выражение, заключенное в разделители. Разделителем по умолчанию для regex в sed является косая черта (/).

Поскольку / является разделителем regex, любое использование / внутри regex необходимо избегать (т. Е. Ему предшествует \).
Команда, которая вам нужна:

[110]

Чтобы использовать другой разделитель для регулярного выражения (чтобы избежать необходимости избегать прямой косой черты), вы должны ставить перед ним обратную косую черту, когда он используется в качестве открытого разделителя. (до адреса). Не избегайте его, когда он используется после regex. Выход из него внутри regex говорит sed использовать его буквальное значение.

Команда в этом случае:

[111]

Пример, который вы утверждаете, работает (sed -i "def r numbers" letters), не следует этому шаблону и фактически не работает (по крайней мере, на macOS sed я использую).
Это должно быть sed -i "/def/ r numbers" letters или, если быть более точным, sed -i "/^def$/ r numbers" letters.

5
задан Wim Coenen 7 May 2009 в 22:22
поделиться

5 ответов

To prevent an exception in a handler from propagating to the event generator, the answer is to manually invoke each item in the MultiCast Delegate (i.e. the event handler) inside of a try-catch

All handlers will get called, and the exception won't propagate.

public EventHandler<EventArgs> SomeEvent;

protected void OnSomeEvent(EventArgs args)
{
    var handler = SomeEvent;
    if (handler != null)
    {
        foreach (EventHandler<EventArgs> item in handler.GetInvocationList())
        {
            try
            {
                item(this, args);
            }
            catch (Exception e)
            {
                // handle / report / ignore exception
            }
        }                
    }
}

What remains is for you to implement the logic for what do do when one or more event recipients throws and the others don't. The catch() could catch a specific exception as well and roll back any changes if that is what makes sense, allowing the event recipient to signal the event source that an exceptional situation has occurred.

As others point out, using exceptions as control flow isn't recommended. If it's truly an exceptional circumstance, then by all means use an exception. If you're getting a lot of exceptions you probably want to use something else.

3
ответ дан 14 December 2019 в 13:46
поделиться

Общий шаблон, который вы увидите для фреймворков:

public class Example
{
   public int Counter { get; private set; }

   public void IncreaseCounter()
   {
      OnCounterChanging(EventArgs.Empty);
      this.Counter = this.Counter + 1;
      OnCounterChanged(EventArgs.Empty);
   }

   protected virtual void OnCounterChanged(EventArgs args)
   {
      if (CounterChanged != null)
         CounterChanged(this, args);
   }

   protected virtual void OnCounterChanging(EventArgs args)
   {
      if (CounterChanging != null)
         CounterChanging(this, args);
   }

   public event EventHandler<EventArgs> CounterChanging;
   public event EventHandler<EventArgs> CounterChanged;
}

Если пользователь хочет создать исключение, чтобы предотвратить изменение значения, он должен сделать это в OnCounterChanging () событие вместо OnCounterChanged (). По определению имени (прошедшее время, суффикс -ed), которое подразумевает, что значение было изменено.

Редактировать:

Обратите внимание, что обычно вы хотите держаться подальше от большого количества дополнительных блоков try..catch / finally. поскольку обработчики исключений (включая try..finally) дороги в зависимости от языковой реализации. т.е. у модели с фреймами стека win32 или модели исключений с отображением ПК есть свои плюсы и минусы, однако, если этих фреймов будет слишком много, они оба будут дорогостоящими (либо по пространству, либо по скорости выполнения). Еще одна вещь, о которой нужно помнить при создании фреймворка.

2
ответ дан 14 December 2019 в 13:46
поделиться

В этом случае, я думаю, вам следует воспользоваться репликой от Workflow Foundation. В методе OnCounterChanged окружите вызов делегата общим блоком try-catch. В обработчике catch вам нужно будет сделать то, что по сути является компенсирующим действием - откат счетчика.

0
ответ дан 14 December 2019 в 13:46
поделиться

Well, you could compensate if it was critical:

public void IncreaseCounter()
{
  int oldCounter = this.Counter;
  try {
      this.Counter = this.Counter + 1;
      OnCounterChanged(EventArgs.Empty);
  } catch {
      this.Counter = oldCounter;
      throw;
  }
}

Obviously this would be better if you can talk to the field (since assigning a field won't error). You could also wrap this up in bolierplate:

void SetField<T>(ref T field, T value, EventHandler handler) {
    T oldValue = field;
    try {
         field = value;
         if(handler != null) handler(this, EventArgs.Empty);
    } catch {
         field = oldField;
         throw;
    }
}

and call:

SetField(ref counter, counter + 1, CounterChanged);

or something similar...

1
ответ дан 14 December 2019 в 13:46
поделиться

Will not simply swapping the order of the two lines in IncreaseCounter enforcestrong exception safety for you?

Or if you need to increment Counter before you raise the event:

public void IncreaseCounter()
{
    this.Counter += 1;

    try
    {
        OnCounterChanged(EventArgs.Empty);
    }
    catch
    {
        this.Counter -= 1;

        throw;
    }
}

In a situation where you have more complex state changes (side effects) going on, then it becomes rather more complicated (you might have to clone certain objects for example), but in for this example it would seem quite easy.

0
ответ дан 14 December 2019 в 13:46
поделиться
Другие вопросы по тегам:

Похожие вопросы: