Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Add delegate to event - thread safety

Tags:

c#

It is possible to execute the following code from multiple threads simultaneously.

this._sequencer.Completed += OnActivityFinished; 

Is it thread safe to add delegate to an event handler from multiple threads?

Is it thread safe to remove delegate to from event handler from multiple threads?

What is the simplest and maintainable way of making this thread safe?

like image 413
Maanu Avatar asked Aug 19 '10 13:08

Maanu


People also ask

Are delegate thread safe?

Regarding the invocation of the delegate the answer is yes.Invoking a delegate is thread-safe because delegates are immutable. However, you must make sure that a delegate exists first. This check may require some synchronization mechanisms depending on the level of safety desired.

How are delegates used in event handling?

These delegates have no return type value and take two parameters (an object for the source of the event, and an object for event data). Delegates are multicast, which means that they can hold references to more than one event-handling method. For details, see the Delegate reference page.

Can we use events without delegates?

Yes, you can declare an event without declaring a delegate by using Action. Action is in the System namespace.

How does event work with delegate in C#?

A delegate is a way of telling C# which method to call when an event is triggered. For example, if you click a Button on a form, the program would call a specific method. It is this pointer that is a delegate. Delegates are good, as you can notify several methods that an event has occurred, if you wish so.


2 Answers

If you don’t specify your own event add/remove handlers, the C# compiler generates this add handler (reconstructed by .NET Reflector):

public void add_MyEvent(EventHandler value) {     EventHandler handler2;     EventHandler myEvent = this.MyEvent;     do     {         handler2 = myEvent;         EventHandler handler3 = (EventHandler) Delegate.Combine(handler2, value);         myEvent = Interlocked.CompareExchange<EventHandler>(ref this.MyEvent, handler3, handler2);     }     while (myEvent != handler2); } 

and a remove handler that looks the same but with Delegate.Remove instead of Delegate.Combine.

Notice the use of Interlocked.CompareExchange? This prevents a race condition between updating the event’s backing field and reading from it. Thus, it is thread-safe.

like image 148
Timwi Avatar answered Sep 29 '22 09:09

Timwi


for field-like events adding/removing of handlers is thread-safe. From spec:

When compiling a field-like event, the compiler automatically creates storage to hold the delegate, and creates accessors for the event that add or remove event handlers to the delegate field. In order to be thread-safe, the addition or removal operations are done while holding the lock (§8.12) on the containing object for an instance event, or the type object (§7.6.10.6) for a static event.

However it is true for C# 3.0 and lesser, in C# 4.0 compiler generates lock-free implementation using Interlocked routines (but spec remains the same - bug?)

In custom implementations no one can tell exactly... except maybe the author of code :)

like image 27
desco Avatar answered Sep 29 '22 07:09

desco