Гость
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Вопрос по событиям / 25 сообщений из 35, страница 1 из 2
07.02.2017, 09:23
    #39399799
csprogrammist
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по событиям
Есть класс (пишу по памяти с телефона)
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
public class A {
   public B b {get; set;}

   public A (){
      b = new B ();
      b.Change+= Update;
   }

   void Update (){...}
}


И
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
public class B {

   public event Action Change;

   protected void OnChange (){
      if (change !=null){ //вылетает на этой строке
         change.Invoke ();
      }
}


В классе B создаем событие, в классе A подписываемся на него. Данная конструкция многократно используется в коде и в одном случае не работает. Работает так, как будто нет подписчиков у события. Если при объявлении события инициализировать его пустым делегатом, то, естественно, в методе OnChange класса B проверка на null проходит, но Update класса A не вызывается. В чем может быть проблема?
...
Рейтинг: 0 / 0
07.02.2017, 10:57
    #39399851
hVostt
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по событиям
csprogrammist
Код: c#
1.
2.
3.
4.
protected void OnChange (){
      if (change !=null){ //вылетает на этой строке
         change.Invoke ();
      }



Можно переписать так:

Код: c#
1.
Change?.Invoke();
...
Рейтинг: 0 / 0
07.02.2017, 11:14
    #39399873
csprogrammist
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по событиям
hVosttcsprogrammist
Код: c#
1.
2.
3.
4.
protected void OnChange (){
      if (change !=null){ //вылетает на этой строке
         change.Invoke ();
      }



Можно переписать так:

Код: c#
1.
Change?.Invoke();


1. На работоспособность не повлияет.
2. Использую Framework 4.0 (данная конструкция только от C# v.6)
...
Рейтинг: 0 / 0
07.02.2017, 11:15
    #39399876
csprogrammist
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по событиям
А вот в причине такого "бездействия" пока разобраться не могу. В приложении повсеместно используется IoC и mvvm-framework. Может это как-то влияет.
...
Рейтинг: 0 / 0
07.02.2017, 11:29
    #39399889
buser
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по событиям
csprogrammist, кто на ком стоял... ? IoC тут ни при чем... даже если такую конструкцию вам не отдебажить, то с с контейнерами - можно вешаться. Кто вызывает OnChange ?
...
Рейтинг: 0 / 0
07.02.2017, 11:30
    #39399892
Алексей К
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по событиям
csprogrammistА вот в причине такого "бездействия" пока разобраться не могу. В приложении повсеместно используется IoC и mvvm-framework. Может это как-то влияет.Может есть смысл написать и представить рабочий показательный пример в виде простенького консольного приложения, иллюстрирующий проблему?
...
Рейтинг: 0 / 0
07.02.2017, 11:36
    #39399897
Roman Mejtes
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по событиям
да скорее всего где то отписка происходит или не подписывается, по этому на сферической примере всё будет нормально
...
Рейтинг: 0 / 0
07.02.2017, 11:39
    #39399900
csprogrammist
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по событиям
Алексей КcsprogrammistА вот в причине такого "бездействия" пока разобраться не могу. В приложении повсеместно используется IoC и mvvm-framework. Может это как-то влияет.Может есть смысл написать и представить рабочий показательный пример в виде простенького консольного приложения, иллюстрирующий проблему?
Я больше чем уверен, что в консольном будет работать. Писал, что данная конструкция встречается у меня в коде части и всегда работает. Чуть позже настрочу код.
...
Рейтинг: 0 / 0
07.02.2017, 11:41
    #39399902
csprogrammist
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по событиям
Roman Mejtesда скорее всего где то отписка происходит или не подписывается, по этому на сферической примере всё будет нормально
Это единственный вариант, который и у меня возникает, но с классом B больше "никто не работает". Только в методе Update класса A вызывается метод класса B (в данном методе реализован простой возврат значения и никаких упоминаний о событиях)
...
Рейтинг: 0 / 0
07.02.2017, 11:45
    #39399908
hVostt
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по событиям
csprogrammist1. На работоспособность не повлияет.
2. Использую Framework 4.0 (данная конструкция только от C# v.6)

Повлияет, мой вариант безопасней. Или добавь предварительное сохранение Change в локальную переменную, потом уже проверяй на null. Вот так:

Код: c#
1.
2.
3.
4.
5.
6.
7.
protected void OnChange ()
{
      var change = this.Change;
      if (change != null) {
         change.Invoke();
      }
}



Что касается конструкции ?., это сахар языка, а не платформы.
...
Рейтинг: 0 / 0
07.02.2017, 11:46
    #39399909
hVostt
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по событиям
csprogrammist,

Добавь логгирование на подписку, для этого реализуй события add/remove у события самостоятельно. Будешь знать кто чего когда.
...
Рейтинг: 0 / 0
07.02.2017, 11:59
    #39399919
Сон Веры Павловны
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по событиям
hVosttПовлияет, мой вариант безопасней. Или добавь предварительное сохранение Change в локальную переменную, потом уже проверяй на null. Вот так:

Код: c#
1.
2.
3.
4.
5.
6.
7.
protected void OnChange ()
{
      var change = this.Change;
      if (change != null) {
         change.Invoke();
      }
}


Рихтер, помнится, писал, что компилятор может в результате оптимизации выкинуть локальную переменную, и завещал делать как-то так:
Код: c#
1.
2.
3.
4.
5.
6.
protected void OnChange()
{
  var tmp = Interlocked.CompareExchange(ref Change, null, null);
  if (tmp != null)
    tmp.Invoke();
}


однако меня гложут сомнения, что причина ошибки в том, что отписка происходит во время проверки - автор сам выше писал, что работает так, как будто нет подписчиков у события . Просто где-то косяк в логике выполнения, когда подписки просто не происходит.
...
Рейтинг: 0 / 0
07.02.2017, 12:12
    #39399929
csprogrammist
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по событиям
hVosttcsprogrammist1. На работоспособность не повлияет.
2. Использую Framework 4.0 (данная конструкция только от C# v.6)

Повлияет, мой вариант безопасней. Или добавь предварительное сохранение Change в локальную переменную, потом уже проверяй на null. Вот так:

Код: c#
1.
2.
3.
4.
5.
6.
7.
protected void OnChange ()
{
      var change = this.Change;
      if (change != null) {
         change.Invoke();
      }
}



Что касается конструкции ?., это сахар языка, а не платформы.
У меня так и реализовано, но данная конструкция все равно не является абсолютно потокобезопасной ))
...
Рейтинг: 0 / 0
07.02.2017, 12:21
    #39399940
hVostt
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по событиям
Сон Веры ПавловныРихтер, помнится, писал, что компилятор может в результате оптимизации выкинуть локальную переменную, и завещал делать как-то так:

Или ещё можно указать переменную с помощью KeepAlive в конце функции. Но в целом, достаточно воспользоваться конструкцией event?.Invoke()
...
Рейтинг: 0 / 0
07.02.2017, 12:21
    #39399941
csprogrammist
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по событиям
Сон Веры ПавловныhVosttПовлияет, мой вариант безопасней. Или добавь предварительное сохранение Change в локальную переменную, потом уже проверяй на null. Вот так:

Код: c#
1.
2.
3.
4.
5.
6.
7.
protected void OnChange ()
{
      var change = this.Change;
      if (change != null) {
         change.Invoke();
      }
}


Рихтер, помнится, писал, что компилятор может в результате оптимизации выкинуть локальную переменную, и завещал делать как-то так:
Код: c#
1.
2.
3.
4.
5.
6.
protected void OnChange()
{
  var tmp = Interlocked.CompareExchange(ref Change, null, null);
  if (tmp != null)
    tmp.Invoke();
}


однако меня гложут сомнения, что причина ошибки в том, что отписка происходит во время проверки - автор сам выше писал, что работает так, как будто нет подписчиков у события . Просто где-то косяк в логике выполнения, когда подписки просто не происходит.
Он, вроде, через volatile предлагал реализовывать, чтобы оптимизация не сработала
...
Рейтинг: 0 / 0
07.02.2017, 12:23
    #39399942
hVostt
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по событиям
csprogrammistУ меня так и реализовано, но данная конструкция все равно не является абсолютно потокобезопасной ))

События на основе цепочек делегатов вообще тотальный фейл в архитектуре платформы. Лучше использовать какую-нибудь свою событийную модель, шину событий, двойную диспетчеризацию и т.п.
...
Рейтинг: 0 / 0
07.02.2017, 12:26
    #39399944
csprogrammist
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по событиям
hVosttcsprogrammist,

Добавь логгирование на подписку, для этого реализуй события add/remove у события самостоятельно. Будешь знать кто чего когда.
Реализовал. Подписчики есть, но "никто" не отписывается.
...
Рейтинг: 0 / 0
07.02.2017, 12:30
    #39399949
Сон Веры Павловны
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по событиям
csprogrammistОн, вроде, через volatile предлагал реализовывать, чтобы оптимизация не сработала
Через Thread.VolatileRead, который его не устроил отсутствием генерик-перегрузки, и которая есть у Interlocked.CompareExchange.
...
Рейтинг: 0 / 0
07.02.2017, 12:34
    #39399956
csprogrammist
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по событиям
Господа, прошу прощения. Добрался до кода и перепроверил. Проверку на null проходит и change.Invoke (); выполняет, но Update не срабатывает
...
Рейтинг: 0 / 0
07.02.2017, 12:57
    #39399984
csprogrammist
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по событиям
csprogrammistГоспода, прошу прощения. Добрался до кода и перепроверил. Проверку на null проходит и change.Invoke (); выполняет, но Update не срабатывает
Реализовал по-другому. Класс A у меня создается в классе С. В классе С при создании экземпляра класса A и сделал подписку. Работает.
...
Рейтинг: 0 / 0
07.02.2017, 13:10
    #39400007
csprogrammist
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по событиям
csprogrammistcsprogrammistГоспода, прошу прощения. Добрался до кода и перепроверил. Проверку на null проходит и change.Invoke (); выполняет, но Update не срабатывает
Реализовал по-другому. Класс A у меня создается в классе С. В классе С при создании экземпляра класса A и сделал подписку. Работает.
Типа того
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
public class C {
   public A a;

   public С (){
      a = new A ();

      a.b.Change+= a.Update;
   }
}
...
Рейтинг: 0 / 0
07.02.2017, 17:25
    #39400306
ЕвгенийВ
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по событиям
hVostt
События на основе цепочек делегатов вообще тотальный фейл в архитектуре платформы. .
Почему? А?
...
Рейтинг: 0 / 0
07.02.2017, 20:33
    #39400434
hVostt
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по событиям
ЕвгенийВПочему? А?

Потому что слишком много не очевидного поведения, особенно в многопоточной среде. А всё, что не очевидно, однозначно плохо. По крайне мере в большинстве случаев.
...
Рейтинг: 0 / 0
07.02.2017, 20:48
    #39400438
ЕвгенийВ
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по событиям
hVosttЕвгенийВПочему? А?

Потому что слишком много не очевидного поведения, особенно в многопоточной среде. А всё, что не очевидно, однозначно плохо. По крайне мере в большинстве случаев.
А если соорудить простенький код с событием и попробовать дизассемблировать его, только не убогими поделками от телерика и джетбрайнса?
...
Рейтинг: 0 / 0
07.02.2017, 21:01
    #39400445
hVostt
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по событиям
ЕвгенийВА если соорудить простенький код с событием и попробовать дизассемблировать его, только не убогими поделками от телерика и джетбрайнса?

Убогие? Что же тогда называть богом данные поделки?

Таки что ты хочешь сказать?
...
Рейтинг: 0 / 0
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Вопрос по событиям / 25 сообщений из 35, страница 1 из 2
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]