. NET basic extension series-how events are implemented

Source: Internet
Author: User

Clr via c # This book describes how events are implemented. CLR uses delegate fields to implement events:
// 1. a private delegate field that is initialized to null
Static EventHandler <EventArgs> NewMail = null;

// 2. a public add_Xxx method (where Xxx is the Event name)
// Allows methods to register interest in the event.
Static void add_NewMail (EventHandler <EventArgs> value)
{
// The loop and the call to CompareExchange is all just a fancy way
// Of adding a delegate to the event in a thread-safe way
EventHandler <EventArgs> prevHandler;
EventHandler <EventArgs> tmp = NewMail;
Do
{
PrevHandler = tmp;
EventHandler <EventArgs> newHandler = (EventHandler <EventArgs>) Delegate. Combine (prevHandler, value );
Tmp = Interlocked. CompareExchange <EventHandler <EventArgs> (ref NewMail, newHandler, prevHandler );
} While (tmp! = PrevHandler );
}


// 3. a public remove_Xxx method (where Xxx is the Event name)
// Allows methods to unregister interest in the event.
Public void remove_NewMail (EventHandler <EventArgs> value)
{
// The loop and the call to CompareExchange is all just a fancy way
// Of removing a delegate from the event in a thread-safe way
EventHandler <EventArgs> prevHandler;
EventHandler <EventArgs> tmp = NewMail;
Do
{
PrevHandler = tmp;
EventHandler <EventArgs> newHandler = (EventHandler <EventArgs>) Delegate. Remove (prevHandler, value );
Tmp = Interlocked. CompareExchange <EventHandler <EventArgs> (ref NewMail, newHandler, prevHandler );
} While (tmp! = PrevHandler );
}
 
However, tmp = Interlocked. CompareExchange <EventHandler <EventArgs> (ref NewMail, newHandler, prevHandler );
This sentence is used to assign values. Why don't I use Interlocked. Exchange to directly assign values? Instead, use CompareExchange and (newMail! = PrevHandler.

 
In the case of a single thread, the two cases have the same effect.
In the case of multi-thread concurrency, we can find out why we can only use CompareExchange.
 
Assume that there are two threads A and B, and the Implementation response function is added at the same time, that is, the add_NewMail function is called.
 
Assume that the event NewMail initialization does not have A time response function, A needs to add A FunctionA response function, B needs to add A FunctionB function.
 
Step 1: thread A starts execution. After executing the following sentence, stop execution: EventHandler <EventArgs> newHandler = (EventHandler <EventArgs>) Delegate. combine (prevHandler, value );
NewMail is null, and newHandler is FunctionA. Thread A stops.
 
Step 2: thread B starts to execute and the entire function is executed,
NewMail is FunctionB.
 
Step 3: thread A continues to execute this statement: tmp = Interlocked. CompareExchange <EventHandler <EventArgs> (ref NewMail, newHandler, prevHandler );
Because NewMail = FunctionB at this time, tmp will = FunctionB,
But because prevHandler = FunctionA, NewMail! = PrevHandler, so the NewMail value remains unchanged.
Execute while (tmp! = PrevHandler), you will find tmp! = PrevHandler: the loop will continue until NewMail and prevHandler have the same value.
In this case, it is clear why Exchange cannot be used. If Exchange is used, the value assignment is executed in step 3, and NewMail is set to FunctionA, then FucntionB will not appear in the delegate linked list of the corresponding time function.
 
Why is CompareExchange okay?
In fact, it is the most fundamental principle to use CompareExchange to verify thread concurrency control: If an operation is to be viewed as non-disruptive, then from the beginning to the complete process, the operating environment cannot be changed.
When CompareExchange is used, we can verify that NewMail is the prevHandler in our initial operation. If not, it indicates that the basic environment of the operation has changed and this operation is invalid.
In this way, you can implement concurrency control when lock is not applicable, which is quite subtle.


From Dunnice

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.