Vraag Vraag met betrekking tot waarde / referentietype van gebeurtenissen


Op MSDN heb ik het volgende gevonden:

public event EventHandler<MyEventArgs> SampleEvent;

public void DemoEvent(string val)
{
// Copy to a temporary variable to be thread-safe.
    EventHandler<MyEventArgs> temp = SampleEvent; 

Is het een referentie?
Als dat zo is, begrijp ik de betekenis ervan niet, omdat toen SampleEvent null werd, ook de temp

    if (temp != null)
        temp(this, new MyEventArgs(val));
}

11
2018-04-08 07:16


oorsprong


antwoorden:


Dit is een paranoia-ding met threading. Als een ander thread annuleert de laatste handler net daarna je hebt het gecontroleerd null, het zou kunnen worden  null en je veroorzaakt een uitzondering. Omdat afgevaardigden onveranderlijk zijn, voorkomt het vastleggen van een momentopname van de afgevaardigde in een variabele dat dit gebeurt.

Natuurlijk heeft het de anders bijverschijnsel dat je (in plaats daarvan) uiteindelijk de gebeurtenis kunt verhogen tegen een object dat denkt dat het al is uitgeschreven ...

Maar om te benadrukken - dit is alleen een probleem wanneer meerdere threads zich abonneren op / afmelden voor het object, wat een: zeldzaam is, en b: niet echt wenselijk.


12
2018-04-08 07:20



(Uit wat ik las in Essential C # 4.0)

Kortom, van deze C # -code:

public class CustomEventArgs: EventArgs {…}
public delegate void CustomEventHandler(object sender, CustomEventArgs a);
public event CustomEventHandler RaiseCustomEvent;

de compiler genereert CIL-code (losjes) gelijk aan de volgende C # -code:

public delegate void CustomEventHandler(object sender, CustomEventArgs a);

private CustomEventHandler customEventHandler; // <-- generated by the compiler

public void add_CustomEventHandler(CustomEventHandler handler) {
  System.Delegate.Combine(customEventHandler, handler);
}

public void remove_CustomEventHandler(CustomEventHandler handler) {
  System.Delegate.Remove(customEventHandler, handler);
}

public event CustomEventHandler customEventHandler {
  add { add_customEventHandler(value) }
  remove { remove_customEventHandler(value) }
}

Wanneer u de gebeurtenis kopieert, kopieert u feitelijk de private CustomEventHandler customEventHandler. Aangezien gedelegeerde niet kan worden gewijzigd, wordt de kopie niet beïnvloed door het origineel customEventHandler is gewijzigd. U kunt deze code proberen om te zien wat ik bedoel:

string s1 = "old"; 
string s2 = s1; 
s1 = "new"; // s2 is still "old"

Een ander belangrijk kenmerk om op te merken over de gegenereerde CIL code is dat het CIL-equivalent van de event sleutelwoord blijft in de CIL. Met andere woorden, een gebeurtenis is iets dat de CIL-code herkent uitdrukkelijk; het is niet alleen een C # -constructie. Door een equivalent te behouden event sleutelwoord in de CIL-code, alle talen en editors kunnen bieden speciale functionaliteit omdat ze het evenement als een special kunnen herkennen klaslid.

Ik denk dat je vooral in de war was omdat je dacht dat evenement een suikersyntaxis is voor een klas, toch?


2
2017-10-04 10:39