Дмитрий Нестерук

Блог о программировании — 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? Дам намек: как ключевое слово имя параметра не подсветилось.

Написано Dmitri

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

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

Комментариев: 8

Подписаться на комментарии по RSS.

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

    Юрий

    2 Август 2011 в 9:23

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

    Игорь

    2 Август 2011 в 10:52

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

    sombre hombre

    2 Август 2011 в 10:54

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

      Dmitri

      2 Август 2011 в 20:05

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

    public static bool SafeDispose(this IDisposable self)
    {

    }

    ilya

    2 Август 2011 в 11:44

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

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

    Nevermind

    4 Август 2011 в 21:22


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

Fill in your details below or click an icon to log in:

Логотип WordPress.com

You are commenting using your WordPress.com account. Log Out / Изменить )

Фотография Twitter

You are commenting using your Twitter account. Log Out / Изменить )

Фотография Facebook

You are commenting using your Facebook account. Log Out / Изменить )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

Join 61 other followers