Дмитpий Hecтepук

Блог о программировании — C#, F#, C++, архитектура, и многое другое

Управление подписками на события

8 комментариев

Итак, небольшая заметка на тему того, как я работаю с подписками на события. Проблема такая: у меня есть XMPP-клиент, он генерирует тучу событий, которые хочется отловить, но помимо этого, еще иногда нужно делать reset этому клиенту, напрочь удаляя все подписки и создавая новые.

Для начала, я создаю класс DisposableCollection который умеет вызывать Dispose() на каждом элементе коллекции:

public sealed class DisposableCollection : Collection<IDisposable>, IDisposable
{
  public void Dispose()
  {
    foreach (var obj in this)
      obj.SafeDispose();
  }
}

SafeDispose() в коде выше – это всего лишь Dispose() с проверкой на null. Метод также возвращает «флаг успешности», что порой бывает полезно.

public static bool SafeDispose(this IDisposable thіs)
{
  if (thіs != null)
  {
    thіs.Dispose();
    return true;
  }
  return false;
}

Еще один extension method — это инверсия потока управления для добавления элементов в коллекцию:

public static T AddTo<T>(this T thіs, Collection<T> coll)
{
  coll.Add(thіs);
  return thіs;
}

А теперь всем этим можно пользоваться. Для подписок используем ReactiveExtensions.

public sealed class XmppConnectionManager : IResetable
{
  private XmppClient client;
  private DisposableCollection subscriptions;
  private void InitializeEvents()
  {
    // wire up events
    Observable.FromEventPattern<ExceptionEventArgs>(x => client.OnError += x, x => client.OnError -= x)
      .Subscribe(x => OnError(x.EventArgs))
      .AddTo(subscriptions);
    Observable.FromEventPattern<EventArgs>(x => client.OnLogin += x, x => client.OnLogin -= x)
      .Subscribe(x => OnLogin(x.EventArgs))
      .AddTo(subscriptions);
    ...
  }
}

Соответственно, если нужно вдруг отписаться от всех подписок, это делается очень быстро:

subscriptions.SafeDispose();

А теперь загадка: почему методы расширения, приведенные выше, компилируются несмотря на название параметра thіs? Дам намек: как ключевое слово имя параметра не подсветилось.

Реклама

Written by Dmitri

2 августа 2011 в 6:27

Опубликовано в .NET, C#, rx

комментариев 8

Subscribe to comments with RSS.

  1. Статический метод?

    Юрий

    2 августа 2011 at 9:23

  2. Кирилическая «і» в названии параметра — это жесть. Надо было до такого додуматься :о)

    Игорь

    2 августа 2011 at 10:52

  3. Зная о любви к необычным символам, можно предположить, что в имени параметра используется какой-нибудь символ не из латинского алфавита.

    sombre hombre

    2 августа 2011 at 10:54

    • Именно так! Используется украинская буква i.

      Dmitri

      2 августа 2011 at 20:05

  4. Я взял себе за правило всегда в extention методах именовать входной this параметр как «self».

    public static bool SafeDispose(this IDisposable self)
    {

    }

    ilya

    2 августа 2011 at 11:44

  5. Вот за такой this лично я бы руки отрывал.

    А в остальном ничего метод, удобно.

    Nevermind

    4 августа 2011 at 21:22


Оставить комментарий

Заполните поля или щелкните по значку, чтобы оставить свой комментарий:

Логотип WordPress.com

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

Фотография Twitter

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

Фотография Facebook

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

Google+ photo

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

Connecting to %s

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