powered by simpleCommunicator - 2.0.53     © 2025 Programmizd 02
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Вопрос по событиям
35 сообщений из 35, показаны все 2 страниц
Вопрос по событиям
    #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
Вопрос по событиям
    #39399851
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
csprogrammist
Код: c#
1.
2.
3.
4.
protected void OnChange (){
      if (change !=null){ //вылетает на этой строке
         change.Invoke ();
      }



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

Код: c#
1.
Change?.Invoke();
...
Рейтинг: 0 / 0
Вопрос по событиям
    #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
Вопрос по событиям
    #39399876
csprogrammist
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
А вот в причине такого "бездействия" пока разобраться не могу. В приложении повсеместно используется IoC и mvvm-framework. Может это как-то влияет.
...
Рейтинг: 0 / 0
Вопрос по событиям
    #39399889
Фотография buser
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
csprogrammist, кто на ком стоял... ? IoC тут ни при чем... даже если такую конструкцию вам не отдебажить, то с с контейнерами - можно вешаться. Кто вызывает OnChange ?
...
Рейтинг: 0 / 0
Вопрос по событиям
    #39399892
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
csprogrammistА вот в причине такого "бездействия" пока разобраться не могу. В приложении повсеместно используется IoC и mvvm-framework. Может это как-то влияет.Может есть смысл написать и представить рабочий показательный пример в виде простенького консольного приложения, иллюстрирующий проблему?
...
Рейтинг: 0 / 0
Вопрос по событиям
    #39399897
Roman Mejtes
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
да скорее всего где то отписка происходит или не подписывается, по этому на сферической примере всё будет нормально
...
Рейтинг: 0 / 0
Вопрос по событиям
    #39399900
csprogrammist
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Алексей КcsprogrammistА вот в причине такого "бездействия" пока разобраться не могу. В приложении повсеместно используется IoC и mvvm-framework. Может это как-то влияет.Может есть смысл написать и представить рабочий показательный пример в виде простенького консольного приложения, иллюстрирующий проблему?
Я больше чем уверен, что в консольном будет работать. Писал, что данная конструкция встречается у меня в коде части и всегда работает. Чуть позже настрочу код.
...
Рейтинг: 0 / 0
Вопрос по событиям
    #39399902
csprogrammist
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Roman Mejtesда скорее всего где то отписка происходит или не подписывается, по этому на сферической примере всё будет нормально
Это единственный вариант, который и у меня возникает, но с классом B больше "никто не работает". Только в методе Update класса A вызывается метод класса B (в данном методе реализован простой возврат значения и никаких упоминаний о событиях)
...
Рейтинг: 0 / 0
Вопрос по событиям
    #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
Вопрос по событиям
    #39399909
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
csprogrammist,

Добавь логгирование на подписку, для этого реализуй события add/remove у события самостоятельно. Будешь знать кто чего когда.
...
Рейтинг: 0 / 0
Вопрос по событиям
    #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
Вопрос по событиям
    #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
Вопрос по событиям
    #39399940
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сон Веры ПавловныРихтер, помнится, писал, что компилятор может в результате оптимизации выкинуть локальную переменную, и завещал делать как-то так:

Или ещё можно указать переменную с помощью KeepAlive в конце функции. Но в целом, достаточно воспользоваться конструкцией event?.Invoke()
...
Рейтинг: 0 / 0
Вопрос по событиям
    #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
Вопрос по событиям
    #39399942
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
csprogrammistУ меня так и реализовано, но данная конструкция все равно не является абсолютно потокобезопасной ))

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

Добавь логгирование на подписку, для этого реализуй события add/remove у события самостоятельно. Будешь знать кто чего когда.
Реализовал. Подписчики есть, но "никто" не отписывается.
...
Рейтинг: 0 / 0
Вопрос по событиям
    #39399949
Сон Веры Павловны
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
csprogrammistОн, вроде, через volatile предлагал реализовывать, чтобы оптимизация не сработала
Через Thread.VolatileRead, который его не устроил отсутствием генерик-перегрузки, и которая есть у Interlocked.CompareExchange.
...
Рейтинг: 0 / 0
Вопрос по событиям
    #39399956
csprogrammist
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Господа, прошу прощения. Добрался до кода и перепроверил. Проверку на null проходит и change.Invoke (); выполняет, но Update не срабатывает
...
Рейтинг: 0 / 0
Вопрос по событиям
    #39399984
csprogrammist
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
csprogrammistГоспода, прошу прощения. Добрался до кода и перепроверил. Проверку на null проходит и change.Invoke (); выполняет, но Update не срабатывает
Реализовал по-другому. Класс A у меня создается в классе С. В классе С при создании экземпляра класса A и сделал подписку. Работает.
...
Рейтинг: 0 / 0
Вопрос по событиям
    #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
Вопрос по событиям
    #39400306
Фотография ЕвгенийВ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hVostt
События на основе цепочек делегатов вообще тотальный фейл в архитектуре платформы. .
Почему? А?
...
Рейтинг: 0 / 0
Вопрос по событиям
    #39400434
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ЕвгенийВПочему? А?

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

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

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

Таки что ты хочешь сказать?
...
Рейтинг: 0 / 0
Вопрос по событиям
    #39400475
Фотография LR
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hVostt,

ну х.з., как то, лет 10 назад, мой друг накропал код выстреливать обработчик события в отдельный поток каждому подписчику - он очень удивился высокой производительности (а я нет - всегда верил мокрософтам)
...
Рейтинг: 0 / 0
Вопрос по событиям
    #39400568
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
LR,

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

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

Таки что ты хочешь сказать?
На самом деле компилятор сварганит нечто подобное.
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
.event class [mscorlib]System.EventHandler`1<class JsonRSM.Program/A/MyEventArgs> MyEvent
{
	.addon instance void JsonRSM.Program/A::add_MyEvent(class [mscorlib]System.EventHandler`1<class JsonRSM.Program/A/MyEventArgs>)
	.removeon instance void JsonRSM.Program/A::remove_MyEvent(class [mscorlib]System.EventHandler`1<class JsonRSM.Program/A/MyEventArgs>)
}

.method public hidebysig specialname 
	instance void add_MyEvent (
		class [mscorlib]System.EventHandler`1<class JsonRSM.Program/A/MyEventArgs> 'value'
	) cil managed 
{
	.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = (
		01 00 00 00
	)
	// Method begins at RVA 0x4134
	// Code size 41 (0x29)
	.maxstack 3
	.locals init (
		[0] class [mscorlib]System.EventHandler`1<class JsonRSM.Program/A/MyEventArgs>,
		[1] class [mscorlib]System.EventHandler`1<class JsonRSM.Program/A/MyEventArgs>,
		[2] class [mscorlib]System.EventHandler`1<class JsonRSM.Program/A/MyEventArgs>
	)

	IL_0000: ldarg.0
	IL_0001: ldfld class [mscorlib]System.EventHandler`1<class JsonRSM.Program/A/MyEventArgs> JsonRSM.Program/A::MyEvent
	IL_0006: stloc.0
	// loop start (head: IL_0007)
		IL_0007: ldloc.0
		IL_0008: stloc.1
		IL_0009: ldloc.1
		IL_000a: ldarg.1
		IL_000b: call class [mscorlib]System.Delegate [mscorlib]System.Delegate::Combine(class [mscorlib]System.Delegate, class [mscorlib]System.Delegate)
		IL_0010: castclass class [mscorlib]System.EventHandler`1<class JsonRSM.Program/A/MyEventArgs>
		IL_0015: stloc.2
		IL_0016: ldarg.0
		IL_0017: ldflda class [mscorlib]System.EventHandler`1<class JsonRSM.Program/A/MyEventArgs> JsonRSM.Program/A::MyEvent
		IL_001c: ldloc.2
		IL_001d: ldloc.1
		IL_001e: call !!0 [mscorlib]System.Threading.Interlocked::CompareExchange<class [mscorlib]System.EventHandler`1<class JsonRSM.Program/A/MyEventArgs>>(!!0&, !!0, !!0)
		IL_0023: stloc.0
		IL_0024: ldloc.0
		IL_0025: ldloc.1
		IL_0026: bne.un.s IL_0007
	// end loop
	IL_0028: ret
} // end of method A::add_MyEvent

.method public hidebysig specialname 
	instance void remove_MyEvent (
		class [mscorlib]System.EventHandler`1<class JsonRSM.Program/A/MyEventArgs> 'value'
	) cil managed 
{
	.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = (
		01 00 00 00
	)
	// Method begins at RVA 0x416c
	// Code size 41 (0x29)
	.maxstack 3
	.locals init (
		[0] class [mscorlib]System.EventHandler`1<class JsonRSM.Program/A/MyEventArgs>,
		[1] class [mscorlib]System.EventHandler`1<class JsonRSM.Program/A/MyEventArgs>,
		[2] class [mscorlib]System.EventHandler`1<class JsonRSM.Program/A/MyEventArgs>
	)

	IL_0000: ldarg.0
	IL_0001: ldfld class [mscorlib]System.EventHandler`1<class JsonRSM.Program/A/MyEventArgs> JsonRSM.Program/A::MyEvent
	IL_0006: stloc.0
	// loop start (head: IL_0007)
		IL_0007: ldloc.0
		IL_0008: stloc.1
		IL_0009: ldloc.1
		IL_000a: ldarg.1
		IL_000b: call class [mscorlib]System.Delegate [mscorlib]System.Delegate::Remove(class [mscorlib]System.Delegate, class [mscorlib]System.Delegate)
		IL_0010: castclass class [mscorlib]System.EventHandler`1<class JsonRSM.Program/A/MyEventArgs>
		IL_0015: stloc.2
		IL_0016: ldarg.0
		IL_0017: ldflda class [mscorlib]System.EventHandler`1<class JsonRSM.Program/A/MyEventArgs> JsonRSM.Program/A::MyEvent
		IL_001c: ldloc.2
		IL_001d: ldloc.1
		IL_001e: call !!0 [mscorlib]System.Threading.Interlocked::CompareExchange<class [mscorlib]System.EventHandler`1<class JsonRSM.Program/A/MyEventArgs>>(!!0&, !!0, !!0)
		IL_0023: stloc.0
		IL_0024: ldloc.0
		IL_0025: ldloc.1
		IL_0026: bne.un.s IL_0007
	// end loop
	IL_0028: ret
} // end of method A::remove_MyEvent


Для многопоточной среды самый то.
...
Рейтинг: 0 / 0
Вопрос по событиям
    #39400725
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ЕвгенийВ,

А наезды на JetBrains и Telerik были к чему?


ЕвгенийВНа самом деле компилятор сварганит нечто подобное.

Не вижу у тебя вызова события.

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
namespace TestProject
{
    public class TestC
    {
        public event EventHandler MyEvent;

        protected void OnMyEvent(EventArgs a)
        {
            MyEvent?.Invoke(this, a);
        }

    }
}



IL:

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
.class public auto ansi beforefieldinit 
  TestProject.TestC
    extends [mscorlib]System.Object
{

  .field private class [mscorlib]System.EventHandler MyEvent
  .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() 
    = (01 00 00 00 )
  .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) 
    = (01 00 00 00 00 00 00 00 ) // ........
    // int32(0) // 0x00000000

  .method public hidebysig specialname instance void 
    add_MyEvent(
      class [mscorlib]System.EventHandler 'value'
    ) cil managed 
  {
    .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() 
      = (01 00 00 00 )
    .maxstack 3
    .locals init (
      [0] class [mscorlib]System.EventHandler V_0,
      [1] class [mscorlib]System.EventHandler V_1,
      [2] class [mscorlib]System.EventHandler V_2
    )

    IL_0000: ldarg.0      // this
    IL_0001: ldfld        class [mscorlib]System.EventHandler TestProject.TestC::MyEvent
    IL_0006: stloc.0      // V_0
    // start of loop, entry point: IL_0007
      IL_0007: ldloc.0      // V_0
      IL_0008: stloc.1      // V_1
      IL_0009: ldloc.1      // V_1
      IL_000a: ldarg.1      // 'value'
      IL_000b: call         class [mscorlib]System.Delegate [mscorlib]System.Delegate::Combine(class [mscorlib]System.Delegate, class [mscorlib]System.Delegate)
      IL_0010: castclass    [mscorlib]System.EventHandler
      IL_0015: stloc.2      // V_2
      IL_0016: ldarg.0      // this
      IL_0017: ldflda       class [mscorlib]System.EventHandler TestProject.TestC::MyEvent
      IL_001c: ldloc.2      // V_2
      IL_001d: ldloc.1      // V_1
      IL_001e: call         !!0/*class [mscorlib]System.EventHandler*/ [mscorlib]System.Threading.Interlocked::CompareExchange<class [mscorlib]System.EventHandler>(!!0/*class [mscorlib]System.EventHandler*/&, !!0/*class [mscorlib]System.EventHandler*/, !!0/*class [mscorlib]System.EventHandler*/)
      IL_0023: stloc.0      // V_0
      IL_0024: ldloc.0      // V_0
      IL_0025: ldloc.1      // V_1
      IL_0026: bne.un.s     IL_0007
    // end of loop
    IL_0028: ret          

  } // end of method TestC::add_MyEvent

  .method public hidebysig specialname instance void 
    remove_MyEvent(
      class [mscorlib]System.EventHandler 'value'
    ) cil managed 
  {
    .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() 
      = (01 00 00 00 )
    .maxstack 3
    .locals init (
      [0] class [mscorlib]System.EventHandler V_0,
      [1] class [mscorlib]System.EventHandler V_1,
      [2] class [mscorlib]System.EventHandler V_2
    )

    IL_0000: ldarg.0      // this
    IL_0001: ldfld        class [mscorlib]System.EventHandler TestProject.TestC::MyEvent
    IL_0006: stloc.0      // V_0
    // start of loop, entry point: IL_0007
      IL_0007: ldloc.0      // V_0
      IL_0008: stloc.1      // V_1
      IL_0009: ldloc.1      // V_1
      IL_000a: ldarg.1      // 'value'
      IL_000b: call         class [mscorlib]System.Delegate [mscorlib]System.Delegate::Remove(class [mscorlib]System.Delegate, class [mscorlib]System.Delegate)
      IL_0010: castclass    [mscorlib]System.EventHandler
      IL_0015: stloc.2      // V_2
      IL_0016: ldarg.0      // this
      IL_0017: ldflda       class [mscorlib]System.EventHandler TestProject.TestC::MyEvent
      IL_001c: ldloc.2      // V_2
      IL_001d: ldloc.1      // V_1
      IL_001e: call         !!0/*class [mscorlib]System.EventHandler*/ [mscorlib]System.Threading.Interlocked::CompareExchange<class [mscorlib]System.EventHandler>(!!0/*class [mscorlib]System.EventHandler*/&, !!0/*class [mscorlib]System.EventHandler*/, !!0/*class [mscorlib]System.EventHandler*/)
      IL_0023: stloc.0      // V_0
      IL_0024: ldloc.0      // V_0
      IL_0025: ldloc.1      // V_1
      IL_0026: bne.un.s     IL_0007
    // end of loop
    IL_0028: ret          

  } // end of method TestC::remove_MyEvent

  .method family hidebysig instance void 
    OnMyEvent(
      class [mscorlib]System.EventArgs a
    ) cil managed 
  {
    .maxstack 8

    // [13 9 - 13 10]
    IL_0000: nop          

    // [14 13 - 14 38]
    IL_0001: ldarg.0      // this
    IL_0002: ldfld        class [mscorlib]System.EventHandler TestProject.TestC::MyEvent
    IL_0007: dup          
    IL_0008: brtrue.s     IL_000d
    IL_000a: pop          
    IL_000b: br.s         IL_0015
    IL_000d: ldarg.0      // this
    IL_000e: ldarg.1      // a
    IL_000f: callvirt     instance void [mscorlib]System.EventHandler::Invoke(object, class [mscorlib]System.EventArgs)
    IL_0014: nop          

    // [15 9 - 15 10]
    IL_0015: ret          

  } // end of method TestC::OnMyEvent

  .method public hidebysig specialname rtspecialname instance void 
    .ctor() cil managed 
  {
    .maxstack 8

    IL_0000: ldarg.0      // this
    IL_0001: call         instance void [mscorlib]System.Object::.ctor()
    IL_0006: nop          
    IL_0007: ret          

  } // end of method TestC::.ctor

  .event [mscorlib]System.EventHandler MyEvent
  {
    .addon instance void TestProject.TestC::add_MyEvent(class [mscorlib]System.EventHandler) 
    .removeon instance void TestProject.TestC::remove_MyEvent(class [mscorlib]System.EventHandler) 
  } // end of event TestC::MyEvent
} // end of class TestProject.TestC



Как видим, если использовать вызов через ?., то CompareExchange не нужен, и оптимизация компилятора ничего не уберёт.
...
Рейтинг: 0 / 0
Вопрос по событиям
    #39400727
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Кстати, IL получен через dotPeek
...
Рейтинг: 0 / 0
Вопрос по событиям
    #39401138
Фотография ЕвгенийВ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hVostt,
Таки с потокобезопасностью то все нормально, насколько это возможно?
...
Рейтинг: 0 / 0
Вопрос по событиям
    #39401239
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ЕвгенийВhVostt,
Таки с потокобезопасностью то все нормально, насколько это возможно?

Учитывая, что event это всего лишь абстракция, могли бы реализовать потокобезопасный Invoke. Странно, что этого не сделали. Ещё не нравится реализация цепочек делегатов.
...
Рейтинг: 0 / 0
Вопрос по событиям
    #39401291
Фотография ЕвгенийВ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hVostt,
Цепочка делегатов есть неизменяемая субстанция, самый то для многопоточности!
...
Рейтинг: 0 / 0
Вопрос по событиям
    #39401312
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ЕвгенийВhVostt,
Цепочка делегатов есть неизменяемая субстанция, самый то для многопоточности!

Да ни для чего это не самое то, кроме как для событий. В большинстве случаев лишний и не очевидный оверхед.
...
Рейтинг: 0 / 0
Вопрос по событиям
    #39401478
Фотография ЕвгенийВ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Надеялся что jit оптимизирует, но :(
Код: c#
1.
2.
3.
Action<string> ass = (s) => Console.WriteLine(s);
            ass("test");
            Console.WriteLine("test");


Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
            ass("test");
00352D67  mov         edx,dword ptr ds:[2FB232Ch]  
00352D6D  mov         ecx,dword ptr [ebp-40h]  
00352D70  mov         eax,dword ptr [ecx+0Ch]  
00352D73  mov         ecx,dword ptr [ecx+4]  
00352D76  call        eax  
00352D78  nop  
            Console.WriteLine("test");
00352D79  mov         ecx,dword ptr ds:[2FB232Ch]  
00352D7F  call        72D46640  
00352D84  nop 
...
Рейтинг: 0 / 0
35 сообщений из 35, показаны все 2 страниц
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Вопрос по событиям
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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