Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can C# not automatically provide thread-safe access to events, where C++/CLI can?

Tags:

c#

.net

c++-cli

From the MSDN documentation for EventHandler Delegate:

In contrast to the C# and Visual Basic examples, the Visual C++ example code does not require you to create a thread-safe temporary variable. Visual C++ version automatically provides thread-safe access, enabling you to raise the event directly.

Why can C# not automatically provide thread-safe access to events, where C++/CLI can?

like image 698
user310291 Avatar asked Mar 07 '11 04:03

user310291


People also ask

What does Can-C do for the eyes?

Can-C's ingredients help to soothe and rejuvenate tired eyes, help with macular degeneration, cataracts, and other age-related eye disorders. Can-C eye drops for cataracts contain lubricants, an antioxidant and an anti-glycating agent, N-Acetyl-Carnosine (NAC).

How long does it take for Can-C to work?

The minimum time to see results from Can-C eye drops, which is generally twice per day, is 6 months.

What are the ingredients in Can-C?

Can-C Ingredients. Glycerin, Carboxymethylcellulose, Benzyl Alcohol, N-Acetyl Carnosine, Potassium Bicarbonate, Boric Acid. (These ingredients are not listed by weight).

How long should you use Can-C eye drops?

Do not use this medication for longer than 3 to 4 days at a time.


2 Answers

This post is quite relevant for background info. An event has three accessors: add, remove and raise. Respectively to add an event handler, remove it and to raise the event. The compiler auto-generates one when you don't write an accessor explicitly.

The C++/CLI compiler auto-generates the raise accessor if you don't write one. It uses the pattern you see in C# code with the helper variable that avoids the null reference exception. Just as you see it in the linked post. For some mysterious reason the C# language doesn't do this. It doesn't even let you define your own accessor, you have to raise the event yourself. Forcing you to write code with the helper variable.

I have no clue why the C# team made this decision. As a rule, the team strongly favors avoiding auto-generated code that slows down execution. The C++ principle of 'you don't pay for what you don't use'. There are certainly many cases where the thread-safety is unnecessary, any events in GUI code for example. This is a heck of an edge-case though, given the low cost and the fact that GUI code contains the pattern anyway. Low-level locking in C++ libraries is however common.

like image 199
Hans Passant Avatar answered Oct 12 '22 15:10

Hans Passant


While not exactly a duplicate, I believe the answers in this question will help explain why they aren't thread safe in terms of implementation. Specifically these two answers.

Marc Gravell's answer:

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 28
Jeff Swensen Avatar answered Oct 12 '22 15:10

Jeff Swensen