[ lukeguy @ 08.05.2010. 10:37 ] @
Do sada sam često nailazio na ovakav kod:
Code (csharp):
public event EventHandler<EventArgs> MyPropertyChanged;

private void InvokeMyPropertyChanged(EventArgs e)
        {
            var handler = MyPropertyChanged;
            if(handler != null)
            {
                handler(this, e);
            }
        }

private void SomeMethod(int value)
        {
            MyProperty = value;
            InvokeMyPropertyChanged(new EventArgs());
        }
 


Ali nisam nigde našao objašnjenje zbog čega je dobra praksa da se kešira event handler u invocator metodi.

Da li je ovakav invocation thread-safe ili postoje neki drugi razlozi? Hvala!
[ ravni @ 08.05.2010. 13:18 ] @
licno, nisam nikad video takav kod, a i nikakvog kesiranja tu nema
handler je lokalna promenljiva ako na nju mislis
[ mmix @ 08.05.2010. 13:50 ] @
da, upravo zbog threadsafety. MyPropertyChanged moze da ode na null izmedju if i invoke i ne samo to nego moze da bude i collected, stavljanjem u handler promenljivu se osiguravas od te dve stvari, da handler ne moze biti null i da event handler (tj instanca koja ga sadrzi) nece biti collectovan dok se ne obavi poziv handlera.
[ lukeguy @ 08.05.2010. 16:26 ] @
ok, tako sam i mislio, jedino nisam bio siguran da li je to jedini razlog. hvala na odgovoru!
[ ravni @ 10.05.2010. 22:16 ] @
to deluje pogresno... onda bi svaki properti morao da 'kesiras' :S
[ mmix @ 10.05.2010. 22:32 ] @
One koji su thread sensitive moras. Nije to pogresno, ovo je jos i najjednostavniji nacin da osiguras thread safety.
[ Boris B. @ 11.05.2010. 00:27 ] @
Pa i nije neki thread safety moram da priznam :)

Ono sa cisto tehnicko-teorijske strane mozda i jeste, ali u praksi ako se je neki objekat odjavio sa event handlera znaci da ne zeli/ne predvidja vise da reaguje na taj event. IMHO u 99% slucajeva se posle odjave pokrene i neki teardown, npr oslobadjanje kesa, disconnect ili sl. Pokretanje hendlera "na silu" u tom trenutku bi bilo veoma pogresno, tj pojavljuju se problemi koje si upravo hteo tim "kesiranjem" reference da izbegnes, samo na drugom mestu.
[ mmix @ 11.05.2010. 07:55 ] @
Pa najbolji je koji imas u tom trenutku za tu primenu, mada se slazem da bi to moglo da se pojaca kroz nacin na koji se instanciraju i odrzavaju Multicast delegati. KOntam da prvo mraju da se dese tone bagova sa novim paralelizmom da bi obratili paznju.

A pokretanje handlera "na silu" nije pogresno a znam i zasto mislis da je pogresno (i ja sam mislio svojevremeno), zato sto o tome razmisljas kao C++ programer, kroz immediate execution, dok CLR zapravo odlaze sve sto moze . Ja sam se doduse navikao na to jos kroz COM evente. To sto si se odjavio sa eventa ne znaci da si rekao da neces vise da primas pozive, vec da ne zelis da ih primas, zvuci slicno ali nije. U COMu npr je slicna prica, kad invoker poziva event sink prvo poziva njegov AddRef() da se osigura da event sink ne nestane u pola posla

Isto tako, ne smes da pretpostavis da ce tvoja instanca umreti onog trenutka kad tebi vise nije potrebna, sve i da nema vise zivih referenci GC moze da je odrzi u zivotu jos veoma veoma dugo (narocito ako je zavrsila u Gen2 na masini sa puno rama) a posebno sto je neko drugi u medjuvremenu mogao da uzme referencu (kao sto je ovde slucaj) pa GC ni ne moze da je pokupi. Teardown state-a o kome pricas da bi bio "koser" mora da se desi kroz disposable patern, i onda ni tu nema problema, samo kod u event handleru uokviris u if (!disposed) {...} i problem resen, kad pravis disposable klasu na to moras svejedno da racunas, na cinjenicu da public metode, interface metode i event hanlderi MOGU biti pozvani nakon Dispose(). Ti mozes da sredis svoju klasu koja ima handler, covek koji pravi klasu sa eventom ne moze da pretpostavi ko ce sve biti kacen na njegov event i kako i mora da se osigura da event ne pukne kod njega sa {"Object reference not set to an instance of an object."}

[ Boris B. @ 18.06.2011. 19:38 ] @
Bajata tema, ali zanimljiva . Slučajno sam naleteo na ovaj blog post i setio se ove teme, pa rek'o da podelim:

http://blogs.msdn.com/b/ericli...09/04/29/events-and-races.aspx