Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Event handlers not thread safe? [duplicate]

So i've read around that instead of calling a event directly with

if (SomeEvent != null)    SomeEvent(this, null); 

i should be doing

SomeEventHandler temp = SomeEvent; if (temp != null)     temp(this, null); 

Why is this so? How does the second version become thread safe? What is the best practice?

like image 986
Daniel Avatar asked Apr 06 '10 01:04

Daniel


People also ask

Are event handlers thread safe?

Bug: EventHandler is not thread safe.

What are events in C# with example?

Events are user actions such as key press, clicks, mouse movements, etc., or some occurrence such as system generated notifications. Applications need to respond to events when they occur. For example, interrupts.


2 Answers

IMO, the other answers miss one key detail - that delegates (and therefore events) are immutable. The significance of this is that subscribing or unsubscribing an event handler doesn't simply append/remove to a list - rather, it replaces the list with a new one with an extra (or one less) item on it.

Since references are atomic, this means that at the point you do:

var handler = SomeEvent; 

you now have a rigid instance that cannot change, even if in the next picosecond another thread unsubscribes (causing the actual event field to become null).

So you test for null and invoke it, and all is well. Note of course that there is still the confusing scenario of the event being raised on an object that thinks it unsubscribed a picosecond ago!

like image 100
Marc Gravell Avatar answered Sep 22 '22 08:09

Marc Gravell


Events are really syntactic sugar over a list of delegates. When you invoke the event, this is really iterating over that list and invoking each delegate with the parameters you have passed.

The problem with threads is that they could be adding or removing items from this collection by subscribing/unsubscribing. If they do this while you are iterating the collection this will cause problems (I think an exception is thrown)

The intent is to copy the list before iterating it, so you are protected against changes to the list.

Note: It is however now possible for your listener to be invoked even after you unsubscribed, so you should make sure you handle this in your listener code.

like image 37
Nigel Thorne Avatar answered Sep 22 '22 08:09

Nigel Thorne