Question

I have a situation in my project where i have connect to multiple server and listen for events. Whenever a event received from the server, Handler should add the event to the common queue for processing. All connections should add received events to the queue.

foreach(var item in collection)
{
        Connection c = new connection(item);

         c.start();
         c.EventReceived+=new EventHandler(myHandler);
         list.add(c);
}

protected void  myHandler(eventArgs)
{
     //add it to the concurrent queue
}

Here i doubt that whether it can be able to handle those events without any threading issues. Please let me know if you have any patterns or built in APIs to handle this safely.

Was it helpful?

Solution

Thread-safety always needs a context - a from what.

If you mean the +=

For the +=, that depends on how the event is implemented. If it is implemented as a field-like event, i.e.

public event SomeEventType EventReceived;

then yes: it is thread-safe. The specification requires that the accessors for field-like events are thread-safe, although the implementation can vary (for example, the MS compiler used to use lock(this) or lock(typeof(DeclaringType)), however it now uses Interlocked instead).

If the event is implemented manually, i.e.

public event SomeEventType EventReceived {
    add { ... }
    remove { ... }
}

Then the thread-safety is defined entirely by the add/remove implementations.

If you mean the invoke

Then that is thread-safe since delegates are immutable, but note that it all happens on the single thread that invokes the thread. However, a common mistake is to introduce a race condition in a null test:

if(EventReceived != null) EventReceived(this, someArgs);

The above is not thread-safe, since technically the value of EventReceived can change after the test. To ensure this does not error, it should be:

var handler = EventReceived;
if(handler != null) handler(this, someArgs);

If you mean the handlers

Then the thread-safety is defined entirely by the individual handlers. For example, in UI applications it is the handlers that must check for, and switch to, the UI thread.

OTHER TIPS

Quoting from C# 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.

Bottom line is if the EventReceived is field like event(non custom implementation) then its thread safe!

Update Current implementation uses Interlocked for thread safety

enter image description here

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top