Äú¿ÉÒÔ¾èÖú£¬Ö§³ÖÎÒÃǵĹ«ÒæÊÂÒµ¡£

1Ôª 10Ôª 50Ôª





ÈÏÖ¤Â룺  ÑéÖ¤Âë,¿´²»Çå³þ?Çëµã»÷Ë¢ÐÂÑéÖ¤Âë ±ØÌî



  ÇóÖª ÎÄÕ ÎÄ¿â Lib ÊÓÆµ iPerson ¿Î³Ì ÈÏÖ¤ ×Éѯ ¹¤¾ß ½²×ù Model Center   Code  
»áÔ±   
   
 
     
   
 ¶©ÔÄ
  ¾èÖú
C# eventḬ̈߳²È«
 
  3751  次浏览      28
 2018-1-8 
 
±à¼­ÍƼö:
±¾ÎÄÀ´×ÔÓÚcnblogs£¬ÎÄÕÂÖ÷ÒªÄÚÈݽéÉÜÁËʹÓÃģʽ£¬ÊµÏÖÕûÀí£¬ÆäÖеı仯£¬²Ù×÷µÄÕýÈ··½Ê½£¬°¸Àý˵Ã÷½ÏΪÏêϸ¡£

ͻȻÏëµ½ÓйØC#ÖÐʹÓÃeventÌØÐÔʱ¹ØÓÚḬ̈߳²È«µÄÎÊÌ⣬ÒÔǰËäÈ»ÓÐ×ñ´Ó¡°¸´ÖÆÒýÓÃ+nullÅжϡ±µÄģʽ£¨Ã¤Ä¿µØ£©£¬µ«Ã»ÓÐÉîÈëÁ˽âºÍ˼¿¼¡£

Ϊ֮²éѯÁË×ÊÁϺÍʵÑ飬¶Ô´ËÓÐÁ˽øÒ»²½µÄÀí½â¡£

Ò»°ãeventʹÓÃģʽ

¶¨Ò壨field-like event£©£º

public event EventHandler Done;

ÀàÄÚraise£º

protected void OnDone()
{
var done = Done;
if (done != null)
{
done(this, new EventArgs());
}
}

²»½ûÒªÎÊ£¬ÎªºÎÒª¸´ÖÆÒýÓã¿¶àÏß³ÌϱíÏÖÈçºÎ£¿

¹ØÓÚC#3.0ºÍC#4.0ÖбàÒëÆ÷¶ÔeventʵÏÖµÄÕûÀí

ΪÁ˽â¾öÉÏÃæÄÄЩÒÉ»ó£¬ÎÒ²éÁËһЩ×ÊÁÏ£¬ÆäÖÐÓÐÀ´×Ôµ±Ê±C#±àÒëÆ÷¿ª·¢×é³ÉÔ±µÄһƪ²©ÎÄ Field-like Events Considered Harmful¡£

ÕâÆª²©ÎĽéÉÜÁËC#3.0ÖбàÒëÆ÷¶ÔÓÚfield-like event£¨Ò²ÊÇ×î³£¼ûµÄʹÓ÷½Ê½£©µÄʵÏÖ¡£

¶ÔÓÚÈç´ËµÄ´úÂ룬

class EventInCS3
{
public event EventHandler Done;
}}

±àÒëÆ÷»á½«Æäת»»³É£º

class EventInCS3
{
private EventHandler __Done; // 1
public event EventHandler Done
{
add
{
lock (this) // 2
{
__Done = __Done + value; // 3
}
}
remove
{
lock (this) { __Done = __Done - value; }
}
}
}

ÓÐÒÔϼ¸µãÖµµÃ×¢Ò⣨ͬעÊͱàºÅ£©£º

1.eventÏÂÒþ²ØµÄÕæÕýdelegateÁ´¡£Êµ¼ÊÉÏÎÒÃÇʹÓõÄÊÇ×ÓÀàMulticastDelegate£¨¿ÉÒԲο¼ ¿ªÔ´µÄcoreclrʵÏÖ£©¡£

3.ÕýÈç+¡¢-²Ù×÷·û¶ÔÓÚstringÀàÐÍÊÇÆð×Ö·û´®×éºÏ×÷Óã¬Æä¶ÔÓÚdelegateÀàÐÍҲͬÑùÊÇÆðµ½Á½ÌõÁ´µÄ×éºÏ×÷Ó㨲ο¼ MSDN£©£¬Êµ¼ÊÉÏÊǵ÷ÓÃÁËDelegate.CombineºÍDelegate.Remove¡£Í¬Ê±Ò²ÒýÈëÁ˾­µäµÄÏß³ÌÎÊÌ⣨Ð޸ĶªÊ§£©¡£

2.ΪÁ˽â¾ö¶àÏß³ÌÎÊÌ⣬ʹÓÃÁËlock¡£

£¨¾ÍÏȲ»¹ÜÕâ¸ölock(this)ÁË¡£µ±È»ÉÏÃæÌáµ½µÄ ²©ÎÄ ÀïÌáµ½ÁË£¬±àÒëÆ÷²¢²»ÊÇͨ¹ýlock£¬¼Ì¶øÍ¨¹ýMonitorµÄ¾²Ì¬·½·¨À´Í¬²½£¬¶øÊÇͨ¹ýIL¼´MethodImplAttribute(MethodImplOptions.Synchronized)ʵÏÖ¡£ÕâЩ¶¼ÊÇC#±¾Éí²»ÍÆ¼öµÄ·½·¨¡££©

¶øÔÚC#4.0ÖУ¬Í¬²½µÄʵÏÖÓÐÁ˱仯£¬Í¬Ñù²Î¼ûͬһ×÷ÕßÁ½ÄêºóµÄ Õâһƪ²©ÎÄ¡£

±àÒëÆ÷ĬÈϵÄadd¡¢removeʵÏÖ£¬¸ÄΪʹÓÃcompare and swapÀ´ÊµÏÖlock-freeͬ²½¡£ÖµµÃ×¢ÒâµÄÊÇ£¬delegateÊDz»¿É¸ü¸ÄµÄÀàÐÍ£¬¼´+=¡¢-=Ö®ºó£¬»áÖ¸ÏòÒ»¸öеĶÔÏ󣬶ø²»ÔÙÊÇÔ­¶ÔÏó£¨ÀàËÆstring£©¡£

ͨ¹ýIL²é¿´³ÌÐò¼¯ÀïÉú³ÉµÄadd_Done¡¢remove_Done£¬¿ÉÒÔ·¢ÏÖ¶ËÄߣ¬´óÖ»áÉú³ÉÈçϵĴúÂ룺

static void add_Done(EventHandler value)
{
EventHandler V_0 = __Done;
EventHandler V_1, V_2;
do
{
V_1 = V_0;
V_2 = (EventHandler)Delegate.Combine(V_1, value);
V_0 = Interlocked.CompareExchange<EventHandler>(ref __Done, V_2, V_1);
} while (V_0 != V_1);
}

C#4.0ÖÐeventÏà¹ØµÄÓïÒå±ä»¯ÕûÀí

ÔÚͬһ×÷ÕßµÄ Áíһƪ²©ÎÄ ÖУ¬½éÉÜÁËC#4.0ÖÐeventÏà¹ØµÄÓïÒå±ä»¯£¬Ö÷ÒªÊÇ+=¡¢-=²Ù×÷·ûµÄÓïÒå±ä»¯¡£

ÔÚC#3.0ÖУ¬¶ÔÓÚÒ»¸öevent£¬Èç¹ûÔÚ¸ÃÀàÖ®Íâ·ÃÎÊÕâ¸öevent£¬Ôò»á±»ÈÏΪÊÇ·ÃÎÊÕâ¸öevent±¾Éí£¬ÈçÎÒÃÇÊìÖªµÄÖ»ÄÜͨ¹ý+=¡¢-=ÕâÁ½¸ö²Ù×÷·ûÀ´·ÃÎÊ£¨¼´Êǵ÷ÓöÔÓ¦µÄadd¡¢remove·ÃÎÊÆ÷£©£»¶øÔÚÀàµÄÄÚ²¿£¬ËùÓжÔÕâ¸öeventµÄ·ÃÎÊ£¬¶¼»á±»ÈÏΪÊÇ·ÃÎÊ×÷ΪeventʵÏÖµÄdelegate±¾Éí£¨¼´·ÃÎÊDone£¬Êµ¼ÊÉÏ·ÃÎʵ½µÄÊÇ__Done£©¡£

Õâô´¦ÀíµÄ»°£¬ÎÒÃǾÍÄÜÔÚOnDone·½·¨Àï¸´ÖÆÒýÓã¬ÅжÏnull£¬½øÐе÷Óá£ÒòΪ´ËʱDoneÕâ¸ö±êʶ·û£¬´ú±íµÄÊÇÒ»¸öEventHandler¶ÔÏóµÄÒýÓá£

C#3.0µÄÎÊÌâÒ²ÔÚÓÚ´Ë£¬ÕâÖÖÇé¿öÏ£¬ÎÒÃÇдÏÂ

Done += SomeHandlerMethod;

ʱ£¬+=ʵ¼ÊÊǵ÷ÓÃÁË£º

EventHandler EventHandler.operator +(EventHandler left, EventHandler right)

ÔÚVisual Studio 2015Àïдһ¸öÆÕͨµÄ¡¢·ÇeventµÄEventHandlerµÄ+=ÔËË㣬Êó±ê·ÅÔÚ+=ÉÏʱ£¬ÏÔʾµÄÒ²ÊÇÕâ¸öº¯ÊýÇ©Ãû¡£C#3.0ʱ¼´Ê¹¶ÔeventÒ²ÊÇÕâô´¦ÀíµÄ¡£

µ¼ÖÂÎÒÃÇʧȥÁËĬÈÏadd·ÃÎÊÆ÷ÌṩµÄͬ²½¹¦ÄÜ¡£

¶øÕâÒ»ÏÖÏóÔÚC#4.0Öеõ½Á˸ÄÉÆ¡£ÔÚÀàÄÚ²¿·ÃÎÊeventµÄ±êʶ·ûʱ£¬+=¡¢-=²Ù×÷·û¾Í»á±»ÈÏΪÊÇadd¡¢removeµÄµ÷ÓÃÁË¡£

¿ÉÖªÔÚC#4.0дÏÂͬÑùµÄ´úÂëʱ£¬+=µ÷ÓõÄÇ©ÃûΪ£º

void EventInCS4.Done.add

×Ô¶¨Òåevent·ÃÎÊÆ÷

×Ô¶¨Òåeventʱ£¨·Çfield-like event£©£¬ÎÒÃÇ×Ô¼º±àдµÄadd¡¢remove·ÃÎÊÆ÷¾ÍûÓÐĬÈϵÄͬ²½ÁË¡£Èç¹ûÒª¿¼ÂÇḬ̈߳²È«£¬ÐèÒªÊÖ¶¯¼ÓÉÏͬ²½£¨±ÈÈçlock(someLockObject)£©¡£

´Ëʱ£¬ÔÚÀàÄÚ²¿·ÃÎÊevent±êʶ·û£¬Ö»»á±»µ±³ÉÊÇ·ÃÎÊevent±¾Éí¡£ÒªÒý·¢Ê¼þ£¨Done£©µÄ»°£¬Ðè·ÃÎʶÔÓ¦delegate£¨__Done(this, new EventArgs())£©¡£

²Ù×÷eventµÄÕýÈ··½Ê½

Ò»°ãÇé¿öÏÂÎÞÐè×Ô¼ºÊµÏÖevent£¬ÓÃfield-like¾ÍºÃÁË¡£

ÒòΪ²»¹ÜÊÇͨ¹ýevent±êʶ·û·ÃÎÊdelegate£¨field-like event£©£¬»¹ÊÇÖ±½Ó·ÃÎÊdelegate£¨×Ô¶¨Òåevent£©£¬ÎÒÃǵõ½µÄ¶¼ÊÇdelegate¶ÔÏóµÄÒýÓ㬶øÇÒdelegate¶ÔÏóÊDz»¿É¸ü¸ÄµÄ¡£ÒýÓõĸ´ÖÆÊÇÔ­×ӵġ£ËùÒÔÎÒÃÇ¿ÉÒÔËæÒâµØ¸´ÖƸÃdelegateµÄÒýÓã¬È»ºóÅжÏnull²¢invoke¡£

һЩcode snippetÈ磺

ͨ¹ýÀ©Õ¹·½·¨À´Òý·¢Ê¼þ£º

public static class EventExtension
{
public static void Raise<T>(this EventHandler<T> handler, object sender, T args)
{
if (handler != null)
{
handler(sender, args);
}
}
public static void Raise(this EventHandler handler, object sender, EventArgs args); // ÖØÔØ°æ
}

delegateµÄÒýÓûáÒÔpass-by-valueÐÎʽµÃµ½¸´ÖÆ£¬ËùÒÔÖ±½Ó

Done.Raise(this, new EventArgs());

ͨ¹ýC#6.0ÌṩµÄNull-conditional²Ù×÷·û£º

Done?.Invoke(this, new EventArgs());

null-conditional²Ù×÷·ûÒ²»á½øÐÐÒýÓõĸ´ÖÆ£¬ËùÒÔÊÇḬ̈߳²È«µÄ¡££¨Ã»ÓÐDone?(...)ÕâÖÖд·¨£©

¸½

¶ÔÓÚ±àÒëÆ÷ÊÇ·ñ»á½«¸´ÖÆÒýÓÃ×÷ÎªÖØ¸´µÄ¾Ö²¿±äÁ¿ÓÅ»¯µô£¬ÒÔÖÁÓÚÔÚһЩÇé¿öÏÂÐèҪʹÓÃÖîÈçÒÔϵķ½Ê½µÄÎÊÌ⣬ÎÒûÓÐÉîÈëÁ˽⡣

Interlocked.CompareExchange(ref Done, null, null);

¼òµ¥²éѯһÏÂÖ®ºó£¬µÃÖª¶ÔÓÚ΢Èí×Ô¼ÒµÄCLRÎÞÐè¹ØÐÄÕâ¸öÎÊÌ⣬¸ÇÆä×ñÑ­½ÏÑϸñµÄÄÚ´æÄ£ÐÍ£¨memory model£©£¬²»»áÒýÈëеĶÁÈ¡²Ù×÷¡£µ«ÆäËûÇé¿öÏÂÓпÉÄÜ´æÔÚÕâÑùµÄÎÊÌâ¡£

   
3751 ´Îä¯ÀÀ       28
 
Ïà¹ØÎÄÕÂ

Éî¶È½âÎö£ºÇåÀíÀôúÂë
ÈçºÎ±àд³öÓµ±§±ä»¯µÄ´úÂë
ÖØ¹¹-ʹ´úÂë¸ü¼ò½àÓÅÃÀ
ÍŶÓÏîÄ¿¿ª·¢"±àÂë¹æ·¶"ϵÁÐÎÄÕÂ
 
Ïà¹ØÎĵµ

ÖØ¹¹-¸ÄÉÆ¼ÈÓдúÂëµÄÉè¼Æ
Èí¼þÖØ¹¹v2
´úÂëÕû½àÖ®µÀ
¸ßÖÊÁ¿±à³Ì¹æ·¶
 
Ïà¹Ø¿Î³Ì

»ùÓÚHTML5¿Í»§¶Ë¡¢Web¶ËµÄÓ¦Óÿª·¢
HTML 5+CSS ¿ª·¢
ǶÈëʽC¸ßÖÊÁ¿±à³Ì
C++¸ß¼¶±à³Ì