C #/. Net basics-safe and effective events C #/. Net basics-safe and effective events

Source: Internet
Author: User

Switch from: render basics-events caused by security and effectiveness

I recently saw a good article on the Internet.ArticleTo discuss how to safely and effectively trigger events.

Maybe you don't have to use the same solution as below, but at least you should know the problems that need to be considered when an event is triggered.

Events

It is very easy to trigger events, but there are indeed some misunderstandings. let's give an example. suppose we write a message receiver. Every time we receive a new message, we trigger an event that contains the new message.Messagereceived.

The common installation method is:

Public ClassMessagereceivedeventargs: eventargs
{
// Received message
Public StringMessage {Get;PrivateSet ;}

// Architecture receivedeventargs
PublicMessagereceivedeventargs (StringMessage)
{
Message = message;
}
}

Next, we will create a non-thread-safe access class.UnsafemessengerTo notify all subscribers (subscriber) at the same time ).

Public ClassUnsafemessenger
{
Public EventEventhandler <messagereceivedeventargs> messagereceived;

// Called when a new message is received
Public VoidOnnewmessage (StringMessage)
{
If(Messagereceived! =Null)
{
Messagereceived (This,NewMessagereceivedeventargs (Message ));
}
}
}

Note thatOnnewmessage ()It is private, but here we set it to public for test convenience.

 

Success !! Yes? In fact, if we are single-threadedProgramThis is enough, but it is not thread-safe ).

Why? Think about it. A subscriber can subscribe to or unsubscribe at any time. For example, if we have a subscriber, when we receive a new message, execute this statement:

 
If (messagereceived! = NULL)
 
It will certainly pass, because there is a subscriber. If this subscriber executes the command to cancel the subscription at this time:
 
Mymessenger. messagereceived-= mymessagehandler;
 
 
 
SoMessagereceivedThe delegate is null,

 

 

// The if statement has been passed

If(Messagereceived! =Null)
{
// The messagereceived delegate is null, but we will execute this sentence
Messagereceived (This,NewMessagereceivedeventargs (Message ));
}

In this caseNullreferenceexception.

 

Solution 1: Lock it, lock mechanism

When multithreading is allowed, we can use a lock mechanism to prevent a user from subscribing to or canceling a subscription when performing an event, or not triggering an event when performing an operation.


Public Class Syncronizedmessenger: imessenger
{
// Delegate and lock
Private Eventhandler <messagereceivedeventargs> _ messagereceived;
Private Readonly Object _ Raiselock = New Object ();

// Subscription/Unsubscribe Lock Mechanism
Public Event Eventhandler <messagereceivedeventargs> messagereceived
{
Add { Lock (_ Raiselock) {_ messagereceived + = Value ;}}
Remove { Lock (_ Raiselock) {_ messagereceived-= Value ;}}
}



// Event Lock Mechanism

Public Void Onnewmessage ( String Message)
{
Lock (_ Raiselock)
{
If (_ Messagereceived! = Null )
{
_ Messagereceived ( This , New Messagereceivedeventargs (Message ));
}
}
}

}
In this way, if someone tries to subscribe to or cancel the subscription, they must wait for the onnewmessage event to complete, and vice versa. solution 2: Never blank. By default, a subscriber is loaded.

The main problem we are facing is that the delegate may be empty. What if we load a delegate in advance?


Public ClassEmptysubscribermessenger: imessenger
{

// Give it an empty subscriber immediately
Public EventEventhandler <messagereceivedeventargs> messagereceived = (S, e) => {};


// You do not need to check whether the value is null!
Public VoidOnnewmessage (StringMessage)
{
Messagereceived (This,NewMessagereceivedeventargs (Message ));
}

}
Solution 3: create a local delegated copy

Another simple solution is used by many people. The recommended mode is to create a local delegated copy.


Public ClassLocalcopymessenger: imessenger
{
Public EventEventhandler <messagereceivedeventargs> messagereceived;


// Make a copy when an event is triggered
Public VoidOnnewmessage (StringMessage)
{
VaR target = messagereceived;

If(Target! =Null)
{
Target (This,NewMessagereceivedeventargs (Message ));
}
}
}

The efficiency of the above four methods is as follows:

Translated from: C #/. Net fundamentals: safely and efficiently raising events

Summary

There is a programming method called cargo cult programming. Chinese name: Goods worship programming. Wikipedia is defined"

Its features are as follows:CodeOr program architecture. Cargo worship programming is usually a typical manifestation of a programmer neither understanding the bugs he wants to solve nor understanding the apparent solutions.

This term sometimes refers to an unfamiliar or inexperienced programmer copying code from one place to another, but it is not clear how the code works, or it is unclear whether this code is needed in the new place. It can also be an incorrect or excessive application design pattern, code style or programming method, but its principle is not clear. "

I admit that in "holding high pragmatism" (How do people make a happy ASP. for efficiency, I often do this. -- Who has time to test third-party controls?

Since this scheme for creating local delegated copies was recommended by the experts, everyone is using it, and some people may not understand the story behind it.

Some friends who have time can talk about the wild history in. NET and expand their programming capabilities. This is more beneficial than chatting about which star has been potential rules ~~~

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.