Re[8]: Событийно ориентированное программирование
От: ionoy Эстония www.ammyui.com
Дата: 22.07.14 07:48
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Здравствуйте, ionoy, Вы писали:


I>>Удобнее тем, что внешнему коду не нужно знать конкретный тип обработчика, чтобы отменить операцию.

S>Что такое "конкретный тип обработчика"?

event EventHandler<bool> Event1;
event EventHandler<string> Event2;
        
public void Subscribe()
{
    EventHandler<bool> handler1 = (sender, b) => { };
    EventHandler<string> handler2 = (sender, s) => { };

    Event1 += handler1;
    Event2 += handler2;

    Unsubscribe(handler1, handler2);
}

private void Unsubscribe(EventHandler<bool> handler1, EventHandler<string> handler2)
{
    Event1 -= handler1;
    Event2 -= handler2;
}


В данном случае EventHandler<bool> и EventHandler<string> это конкретные типы обработчиков.
Я не могу написать:
void Unsubscribe(IEnumerable<EventHandler<T>> handlers) {
  foreach(var handler in handlers)
    //somehow unsubscribe?  
}

Потому что источники событий могут быть разные (Event1, Event2 и любая другая подписка).
Получается, что методу отписки нужно знать не только тип обработчика, но и само событие от которого нужно отписаться. Далеко не всегда есть возможность эту информацию предоставить.

S>Непонятно, почему именно Disposable.

S>Почему вы не хотите комбинировать, например, Action.
Из-за разных наборов параметров.
www.livexaml.com
www.ammyui.com
www.nemerleweb.com
Re[9]: Событийно ориентированное программирование
От: ionoy Эстония www.ammyui.com
Дата: 22.07.14 07:51
Оценка:
Здравствуйте, ionoy, Вы писали:

S>>Непонятно, почему именно Disposable.

S>>Почему вы не хотите комбинировать, например, Action.
I>Из-за разных наборов параметров.

Дополню:
И необходимости передавать источник. От самого Action толку мало, в отличие от IDisposable.
www.livexaml.com
www.ammyui.com
www.nemerleweb.com
Re[10]: Событийно ориентированное программирование
От: dimgel Россия https://github.com/dimgel
Дата: 22.07.14 07:55
Оценка: 1 (1)
Здравствуйте, ionoy, Вы писали:

I>в отличие от IDisposable.


SRP, кстати, опять же.
Re[10]: Событийно ориентированное программирование
От: Sinclair Россия https://github.com/evilguest/
Дата: 22.07.14 10:55
Оценка:
Здравствуйте, ionoy, Вы писали:

I>Дополню:

I>И необходимости передавать источник. От самого Action толку мало, в отличие от IDisposable.
А, я, наверное, непонятно выразился.
вот что я имел в виду:
public Action Subscribe() {
  EventHandler<bool> handler1 = (sender, b) => { };
  EventHandler<string> handler2 = (sender, s) => { };

  Action unsubscribe = () => {
    Event1 -= handler1;
  };
  г
  return unsubscribe;
}

Как видим, внешнему коду вообще не нужно знать ни тип обработчика, ни конкретное событие. Достаточно позвать делегат, который ему вернули, в тот момент, когда вы хотели вызывать IDisposable.Dispose.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[11]: Событийно ориентированное программирование
От: ionoy Эстония www.ammyui.com
Дата: 22.07.14 11:14
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>А, я, наверное, непонятно выразился.

S>вот что я имел в виду:
S>
S>public Action Subscribe() {
S>  EventHandler<bool> handler1 = (sender, b) => { };
S>  EventHandler<string> handler2 = (sender, s) => { };

S>  Action unsubscribe = () => {
S>    Event1 -= handler1;
S>  };
S>  г
S>  return unsubscribe;
S>}
S>

S>Как видим, внешнему коду вообще не нужно знать ни тип обработчика, ни конкретное событие. Достаточно позвать делегат, который ему вернули, в тот момент, когда вы хотели вызывать IDisposable.Dispose.

Примерно так оно и работает внутри. Есть, например, удобный метод:

Disposable.Create(() => Debug.WriteLine("Dispose called"));


Как я это вижу, у IDisposable есть несколько преимуществ перед Action:

1. На основании этого интерфейса можно создать готовую библиотеку реализаций IDisposable, как сделали в Rx. Такие объекты предоставляют дополнительную функциональность для кода выдающего подписку, а для клиентов всё тот же IDisposable. Про некоторые готовые реализации опять же здесь: http://synchronicity-life.blogspot.com/2011/12/idisposable-implementations-in-reactive.html
2. IDisposable — это распространённый шаблон проектирования. Иногда бывает удобно локализовать подписку с помощью using.
3. IDisposable семантически лучше подходит на роль отписчика, чем Action
www.livexaml.com
www.ammyui.com
www.nemerleweb.com
Re[12]: Событийно ориентированное программирование
От: Sinclair Россия https://github.com/evilguest/
Дата: 22.07.14 12:00
Оценка:
Здравствуйте, ionoy, Вы писали:

I>Примерно так оно и работает внутри. Есть, например, удобный метод:


I>
I>Disposable.Create(() => Debug.WriteLine("Dispose called"));
I>


I>Как я это вижу, у IDisposable есть несколько преимуществ перед Action:

Ну так и используйте его, если в вашей инфраструктуре он удобнее.
Лично мне более удобными кажутся weak events, т.к. сама необходимость следить за отпиской напрягает. Независимо от того, используется ли "честный" OnClick -=, Action, или IDisposable.
Я очень часто сталкивался с тем, что нам нужен "observer, который следит, покуда жив", а не "observer, который жив, покуда следит".
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[13]: Событийно ориентированное программирование
От: ionoy Эстония www.ammyui.com
Дата: 22.07.14 14:16
Оценка:
Здравствуйте, Sinclair, Вы писали:

I>>Как я это вижу, у IDisposable есть несколько преимуществ перед Action:

S>Ну так и используйте его, если в вашей инфраструктуре он удобнее.
S>Лично мне более удобными кажутся weak events, т.к. сама необходимость следить за отпиской напрягает. Независимо от того, используется ли "честный" OnClick -=, Action, или IDisposable.
S>Я очень часто сталкивался с тем, что нам нужен "observer, который следит, покуда жив", а не "observer, который жив, покуда следит".

Многие Observable так и устроены.

Например, такой код:
stream.Take(3).Subscribe(x => DoSomething(x))

сам отпишет подписчика. IDisposable нужен только в тех случаях, когда ты сам хочешь выбирать момент где переставать следить за потоком.
www.livexaml.com
www.ammyui.com
www.nemerleweb.com
Re[14]: Событийно ориентированное программирование
От: Sinclair Россия https://github.com/evilguest/
Дата: 22.07.14 17:54
Оценка:
Здравствуйте, ionoy, Вы писали:
I>сам отпишет подписчика.
Это понятно. Есть обратные ситуации — datasource.OnChange += form1.Refresh навсегда удержит форму в памяти.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[6]: Событийно ориентированное программирование
От: _NN_ www.nemerleweb.com
Дата: 23.07.14 03:56
Оценка:
Здравствуйте, Sinclair, Вы писали:

В том, что нельзя допустить вроде этой: http://www.rsdn.ru/forum/philosophy/5699473.1
Автор: _NN_
Дата: 19.07.14

Или в стиле шарпа:
void Resubscribe()
{
  Action myHandler = () => {};
  a.OnClick -= myHandler;
  a.OnClick += myHandler;
}
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[7]: Событийно ориентированное программирование
От: Jack128  
Дата: 23.07.14 06:20
Оценка:
Здравствуйте, _NN_, Вы писали:

_NN>Здравствуйте, Sinclair, Вы писали:


_NN>В том, что нельзя допустить вроде этой: http://www.rsdn.ru/forum/philosophy/5699473.1
Автор: _NN_
Дата: 19.07.14

_NN>Или в стиле шарпа:
_NN>
_NN>void Resubscribe()
_NN>{
_NN>  Action myHandler = () => {};
_NN>  a.OnClick -= myHandler;
_NN>  a.OnClick += myHandler;
_NN>}
_NN>


а как ты такое в варианте с IDisposable реализуешь ?
Re[15]: Событийно ориентированное программирование
От: ionoy Эстония www.ammyui.com
Дата: 23.07.14 06:27
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Здравствуйте, ionoy, Вы писали:

I>>сам отпишет подписчика.
S>Это понятно. Есть обратные ситуации — datasource.OnChange += form1.Refresh навсегда удержит форму в памяти.
Так ведь можно отписаться по необходимости. Или я чего-то не понимаю?
www.livexaml.com
www.ammyui.com
www.nemerleweb.com
Re[8]: Событийно ориентированное программирование
От: _NN_ www.nemerleweb.com
Дата: 23.07.14 07:07
Оценка:
Здравствуйте, Jack128, Вы писали:

J>а как ты такое в варианте с IDisposable реализуешь ?


Например так:

IDisposable subscription;

void Resubscribe()
{
  subscription.Dispose();
  subscription = a.OnClick.Subscribe(myHandler);
}


Главное то, что я не смогу написать код, который якобы отписывается, а на деле ничего не делает.
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[16]: Событийно ориентированное программирование
От: Sinclair Россия https://github.com/evilguest/
Дата: 23.07.14 09:57
Оценка:
Здравствуйте, ionoy, Вы писали:
S>>Это понятно. Есть обратные ситуации — datasource.OnChange += form1.Refresh навсегда удержит форму в памяти.
I>Так ведь можно отписаться по необходимости. Или я чего-то не понимаю?
Что значит "по необходимости"? Как вы определите момент необходимости?
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[17]: Событийно ориентированное программирование
От: ionoy Эстония www.ammyui.com
Дата: 23.07.14 10:08
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Здравствуйте, ionoy, Вы писали:

S>>>Это понятно. Есть обратные ситуации — datasource.OnChange += form1.Refresh навсегда удержит форму в памяти.
I>>Так ведь можно отписаться по необходимости. Или я чего-то не понимаю?
S>Что значит "по необходимости"? Как вы определите момент необходимости?

Вопрос был в том, что привязка навсегда удержит форму в памяти. Если есть такая проблема, значит когда-то эта форма перестаёт быть нужной? Обычно момент удаления формы более или менее детерминирован.
www.livexaml.com
www.ammyui.com
www.nemerleweb.com
Re[7]: Событийно ориентированное программирование
От: Sinclair Россия https://github.com/evilguest/
Дата: 23.07.14 10:17
Оценка:
Здравствуйте, _NN_, Вы писали:

_NN>В том, что нельзя допустить вроде этой: http://www.rsdn.ru/forum/philosophy/5699473.1
Автор: _NN_
Дата: 19.07.14

_NN>Или в стиле шарпа:
_NN>
_NN>void Resubscribe()
_NN>{
_NN>  Action myHandler = () => {};
_NN>  a.OnClick -= myHandler;
_NN>  a.OnClick += myHandler;
_NN>}
_NN>

Ничего не понял. По ссылке — абсолютно работоспособный пример. На событие подписывается ровно одна функция.
В этом коде — тоже. На какой вопрос вы отвечаете — непонятно.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[18]: Событийно ориентированное программирование
От: Sinclair Россия https://github.com/evilguest/
Дата: 23.07.14 10:48
Оценка:
Здравствуйте, ionoy, Вы писали:
I>Вопрос был в том, что привязка навсегда удержит форму в памяти. Если есть такая проблема, значит когда-то эта форма перестаёт быть нужной?
Обычно (в среде с недетерминистической финализацией) объект перестаёт быть нужен тогда, когда последняя ссылка на него выходит из области видимости.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[9]: Событийно ориентированное программирование
От: Jack128  
Дата: 23.07.14 10:48
Оценка:
Здравствуйте, _NN_, Вы писали:

_NN>Например так:


_NN>
_NN>IDisposable subscription;

_NN>void Resubscribe()
_NN>{
_NN>  subscription.Dispose();
_NN>  subscription = a.OnClick.Subscribe(myHandler);
_NN>}
_NN>


ну ты сохранил подписку в глобальной переменной. точно так же и лямбду можно сохранить. в чем отличие ?
Re[19]: Событийно ориентированное программирование
От: ionoy Эстония www.ammyui.com
Дата: 23.07.14 12:06
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Здравствуйте, ionoy, Вы писали:

I>>Вопрос был в том, что привязка навсегда удержит форму в памяти. Если есть такая проблема, значит когда-то эта форма перестаёт быть нужной?
S>Обычно (в среде с недетерминистической финализацией) объект перестаёт быть нужен тогда, когда последняя ссылка на него выходит из области видимости.

Ссылка сама по себе не выходит из области видимости, какой-то код управляет этим процессом, в любом случае. Может просто пример с формой неудачный, т.к. там нет проблем отследить закрытие
www.livexaml.com
www.ammyui.com
www.nemerleweb.com
Re[20]: Событийно ориентированное программирование
От: Sinclair Россия https://github.com/evilguest/
Дата: 23.07.14 17:27
Оценка:
Здравствуйте, ionoy, Вы писали:

I>Ссылка сама по себе не выходит из области видимости, какой-то код управляет этим процессом, в любом случае.

Да ладно!
Ещё как выходит. Если бы это было не так, то нам вообще бы не потребовался сборщик мусора — мы всегда бы знали, в какой момент пора звать деструктор и освобождать память

I>Может просто пример с формой неудачный, т.к. там нет проблем отследить закрытие

Да. С формой пример не совсем удачный, т.к. в ней есть явный Dispose, в котором можно сделать отписку и полагаться на компонентную модель в контроле времени жизни. И тем не менее — ошибку типа "забыл отписаться" сделать очень легко. Эта возможность граблей никуда не денется от того, что оператор += будет возвращать что-то другое. Нам всё равно нужно куда-то записывать ссылку, либо на IDisposable, который надо не забыть отдиспозить, либо на хэндлер, который нужно отписать.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[21]: Событийно ориентированное программирование
От: ionoy Эстония www.ammyui.com
Дата: 23.07.14 18:46
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Здравствуйте, ionoy, Вы писали:


I>>Ссылка сама по себе не выходит из области видимости, какой-то код управляет этим процессом, в любом случае.

S>Да ладно!
S>Ещё как выходит. Если бы это было не так, то нам вообще бы не потребовался сборщик мусора — мы всегда бы знали, в какой момент пора звать деструктор и освобождать память
А можно пример, где ссылка сама по себе выходит из области видимости, но при этом остаётся в памяти из-за привязки к событию?

I>>Может просто пример с формой неудачный, т.к. там нет проблем отследить закрытие

S>Да. С формой пример не совсем удачный, т.к. в ней есть явный Dispose, в котором можно сделать отписку и полагаться на компонентную модель в контроле времени жизни. И тем не менее — ошибку типа "забыл отписаться" сделать очень легко. Эта возможность граблей никуда не денется от того, что оператор += будет возвращать что-то другое. Нам всё равно нужно куда-то записывать ссылку, либо на IDisposable, который надо не забыть отдиспозить, либо на хэндлер, который нужно отписать.
Это верно, ошибиться можно. Другое дело, что про эти грабли разве что глухой не слышал.
www.livexaml.com
www.ammyui.com
www.nemerleweb.com
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.