
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN" "http://www.wapforum.org/DTD/wml_1.1.xml">
<wml>
	<head><meta forua="true" http-equiv="Cache-Control" content="max-age=0" /></head><card id="MainCard" title="&#x6B22;&#x8FCE;&#x5149;&#x4E34;"><p><a href="wap.asp">&#x6728;&#x5B50;&#x5C4B;</a><br/>&nbsp;</p><p><b>&#x6807;&#x9898;&#x3A;</b> &#x45;&#x66;&#x66;&#x65;&#x63;&#x74;&#x69;&#x76;&#x65;&#x20;&#x43;&#x23;&#x20;&#x539F;&#x5219;&#x32;&#x32;&#xFF1A;&#x7528;&#x4E8B;&#x4EF6;&#x5B9A;&#x4E49;&#x5BF9;&#x5916;&#x63A5;&#x53E3;</p><p><b>&#x4F5C;&#x8005;&#x3A;</b> &#x64;&#x6E;&#x61;&#x77;&#x6F;</p><p><b>&#x65E5;&#x671F;&#x3A;</b> &#x32;&#x30;&#x30;&#x39;&#x2D;&#x31;&#x32;&#x2D;&#x33;&#x31;&#x20;&#x30;&#x39;&#x3A;&#x32;&#x36;&#x20;&#x41;&#x4D;</p><p><b>&#x5206;&#x7C7B;&#x3A;</b> <a href="wap.asp?do=showLog&amp;cateID=5">&#x57;&#x65;&#x62;&#x7F16;&#x7A0B;</a></p><p><b>&#x5185;&#x5BB9;&#x3A;</b> &#x53EF;&#x4EE5;&#x7528;&#x4E8B;&#x4EF6;&#x7ED9;&#x4F60;&#x7684;&#x7C7B;&#x578B;&#x5B9A;&#x4E49;&#x4E00;&#x4E9B;&#x5916;&#x90E8;&#x63A5;&#x53E3;&#x3002;&#x4E8B;&#x4EF6;&#x662F;&#x57FA;&#x4E8E;&#x59D4;&#x6258;&#x7684;&#xFF0C;&#x56E0;&#x4E3A;&#x59D4;&#x6258;&#x53EF;&#x4EE5;&#x63D0;&#x4F9B;&#x7C7B;&#x578B;&#x5B89;&#x5168;&#x7684;&#x51FD;&#x6570;&#x7B7E;&#x540D;&#x5230;&#x4E8B;&#x4EF6;&#x53E5;&#x67C4;&#x4E0A;&#x3002;&#x52A0;&#x4E0A;&#x5927;&#x591A;&#x6570;&#x59D4;&#x6258;&#x7684;&#x4F8B;&#x5B50;&#x90FD;&#x662F;&#x4F7F;&#x7528;&#x4E8B;&#x4EF6;&#x6765;&#x8BF4;&#x660E;&#x7684;&#xFF0C;&#x4EE5;&#x81F3;&#x4E8E;&#x5F00;&#x53D1;&#x4EBA;&#x5458;&#x4E00;&#x5F00;&#x59CB;&#x90FD;&#x8BA4;&#x4E3A;&#x59D4;&#x6258;&#x4E0E;&#x4E8B;&#x4EF6;&#x662F;&#x4E00;&#x56DE;&#x4E8B;&#x3002;&#x5728;&#x539F;&#x5219;21&#x91CC;&#xFF0C;&#x6211;&#x5DF2;&#x7ECF;&#x5C55;&#x793A;&#x4E86;&#x4E00;&#x4E9B;&#x4E0D;&#x5728;&#x4E8B;&#x4EF6;&#x4E0A;&#x4F7F;&#x7528;&#x59D4;&#x6258;&#x7684;&#x4F8B;&#x5B50;&#x3002;&#x5728;&#x4F60;&#x7684;&#x7C7B;&#x578B;&#x4E0E;&#x5176;&#x5B83;&#x591A;&#x4E2A;&#x5BA2;&#x6237;&#x8FDB;&#x884C;&#x901A;&#x4FE1;&#x65F6;&#xFF0C;&#x4E3A;&#x4E86;&#x5B8C;&#x6210;&#x5B83;&#x4EEC;&#x7684;&#x884C;&#x4E3A;&#xFF0C;&#x4F60;&#x5FC5;&#x987B;&#x5F15;&#x53D1;&#x4E8B;&#x4EF6;&#x3002;<br/>&#x4E00;&#x4E2A;&#x7B80;&#x5355;&#x7684;&#x4F8B;&#x5B50;&#xFF0C;&#x4F60;&#x6B63;&#x5728;&#x505A;&#x4E00;&#x4E2A;&#x65E5;&#x5FD7;&#x7C7B;&#xFF0C;&#x5C31;&#x50CF;&#x4E00;&#x4E2A;&#x4FE1;&#x606F;&#x53D1;&#x5E03;&#x673A;&#x4E00;&#x6837;&#x5728;&#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x91CC;&#x53D1;&#x5E03;&#x6240;&#x6709;&#x7684;&#x6D88;&#x606F;&#x3002;&#x5B83;&#x63A5;&#x53D7;&#x6240;&#x6709;&#x4ECE;&#x7A0B;&#x5E8F;&#x6E90;&#x53D1;&#x5E03;&#x7684;&#x6D88;&#x606F;&#xFF0C;&#x5E76;&#x4E14;&#x628A;&#x8FD9;&#x4E9B;&#x6D88;&#x606F;&#x53D1;&#x5E03;&#x5230;&#x611F;&#x5174;&#x8DA3;&#x7684;&#x542C;&#x4F17;&#x90A3;&#x91CC;&#x3002;&#x8FD9;&#x4E9B;&#x542C;&#x4F17;&#x53EF;&#x4EE5;&#x662F;&#x63A7;&#x5236;&#x53F0;&#xFF0C;&#x6570;&#x636E;&#x5E93;&#xFF0C;&#x7CFB;&#x7EDF;&#x65E5;&#x5FD7;&#xFF0C;&#x6216;&#x8005;&#x662F;&#x5176;&#x5B83;&#x7684;&#x673A;&#x5236;&#x3002;&#x5C31;&#x53EF;&#x4EE5;&#x5B9A;&#x4E49;&#x4E00;&#x4E2A;&#x50CF;&#x4E0B;&#x9762;&#x8FD9;&#x6837;&#x7684;&#x7C7B;&#xFF0C;&#x5F53;&#x6D88;&#x606F;&#x5230;&#x8FBE;&#x65F6;&#x6765;&#x5F15;&#x53D1;&#x4E8B;&#x4EF6;&#xFF1A;<br/>&#x590D;&#x5236;&#x5185;&#x5BB9;&#x5230;&#x526A;&#x8D34;&#x677F; &#x7A0B;&#x5E8F;&#x4EE3;&#x7801;public class LoggerEventArgs : EventArgs<br/>{<br/>&nbsp;&nbsp;public readonly string Message;<br/>&nbsp;&nbsp;public readonly int Priority;<br/>&nbsp;&nbsp;public LoggerEventArgs ( int p, string m )<br/>&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;Priority = p;<br/>&nbsp;&nbsp;&nbsp;&nbsp;Message = m;<br/>&nbsp;&nbsp;}<br/>}<br/>// Define the signature for the event handler:<br/>public delegate void AddMessageEventHandler( object sender,<br/>&nbsp;&nbsp;LoggerEventArgs msg );<br/>public class Logger<br/>{<br/>&nbsp;&nbsp;static Logger( )<br/>&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;_theOnly = new Logger( );<br/>&nbsp;&nbsp;}<br/>&nbsp;&nbsp;private Logger( )<br/>&nbsp;&nbsp;{<br/>&nbsp;&nbsp;}<br/>&nbsp;&nbsp;private static Logger _theOnly = null;<br/>&nbsp;&nbsp;public Logger Singleton<br/>&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;get<br/>&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return _theOnly;<br/>&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;}<br/>&nbsp;&nbsp;// Define the event:<br/>&nbsp;&nbsp;public event AddMessageEventHandler Log;<br/>&nbsp;&nbsp;// add a message, and log it.<br/>&nbsp;&nbsp;public void AddMsg ( int priority, string msg )<br/>&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;// This idiom discussed below.<br/>&nbsp;&nbsp;&nbsp;&nbsp;AddMessageEventHandler l = Log;<br/>&nbsp;&nbsp;&nbsp;&nbsp;if ( l != null )<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;l ( null, new LoggerEventArgs( priority, msg ) );<br/>&nbsp;&nbsp;}<br/>}<br/>AddMsg&#x65B9;&#x6CD5;&#x6F14;&#x793A;&#x4E86;&#x4E00;&#x4E2A;&#x6070;&#x5F53;&#x7684;&#x65B9;&#x6CD5;&#x6765;&#x5F15;&#x53D1;&#x4E8B;&#x4EF6;&#x3002;&#x4E34;&#x65F6;&#x7684;&#x65E5;&#x5FD7;&#x53E5;&#x67C4;&#x53D8;&#x91CF; &#x662F;&#x5F88;&#x91CD;&#x8981;&#x7684;&#xFF0C;&#x5B83;&#x53EF;&#x4EE5;&#x786E;&#x4FDD;&#x5728;&#x5404;&#x79CD;&#x591A;&#x7EBF;&#x7A0B;&#x7684;&#x60C5;&#x51B5;&#x4E0B;&#xFF0C;&#x65E5;&#x5FD7;&#x53E5;&#x67C4;&#x4E5F;&#x662F;&#x5B89;&#x5168;&#x7684;&#x3002;&#x5982;&#x679C;&#x6CA1;&#x6709;&#x8FD9;&#x4E2A;&#x5F15;&#x7528;&#x7684;COPY&#xFF0C;&#x7528;&#x6237;&#x5C31;&#x6709;&#x53EF;&#x80FD;&#x5728;if&#x68C0;&#x6D4B;&#x8BED;&#x53E5;&#x548C;&#x6B63;&#x5F0F;&#x6267;&#x884C;&#x4E8B;&#x4EF6;&#x53E5;&#x67C4;&#x4E4B;&#x95F4;&#x79FB;&#x9664;&#x4E8B;&#x4EF6;&#x53E5;&#x67C4;&#x3002;&#x6709;&#x4E86;&#x5F15;&#x7528;COPY&#xFF0C;&#x8FD9;&#x6837;&#x7684;&#x4E8B;&#x60C5;&#x5C31;&#x4E0D;&#x4F1A;&#x53D1;&#x751F;&#x4E86;&#x3002;<br/>&#x6211;&#x8FD8;&#x5B9A;&#x4E49;&#x4E86;&#x4E00;&#x4E2A;LoggerEventArgs&#x6765;&#x4FDD;&#x5B58;&#x4E8B;&#x4EF6;&#x548C;&#x6D88;&#x606F;&#x7684;&#x4F18;&#x5148;&#x7EA7;&#x3002;&#x59D4;&#x6258;&#x5B9A;&#x4E49;&#x4E86;&#x4E8B;&#x4EF6;&#x53E5;&#x67C4;&#x7684;&#x7B7E;&#x540D;&#x3002;&#x800C;&#x5728;Logger&#x7C7B;&#x7684;&#x5185;&#x90E8;&#xFF0C;&#x4E8B;&#x4EF6;&#x5B57;&#x6BB5;&#x5B9A;&#x4E49;&#x4E86;&#x4E8B;&#x4EF6;&#x7684;&#x53E5;&#x67C4;&#x3002;&#x7F16;&#x8BD1;&#x5668;&#x4F1A;&#x8BA4;&#x4E3A;&#x4E8B;&#x4EF6;&#x662F;&#x516C;&#x5171;&#x7684;&#x5B57;&#x6BB5;&#xFF0C;&#x800C;&#x4E14;&#x4F1A;&#x4E3A;&#x4F60;&#x6DFB;&#x52A0;Add&#x548C;Remove&#x4E24;&#x4E2A;&#x64CD;&#x4F5C;&#x3002;&#x751F;&#x6210;&#x7684;&#x4EE3;&#x7801;&#x4E0E;&#x4F60;&#x8FD9;&#x6837;&#x624B;&#x5199;&#x7684;&#x662F;&#x4E00;&#x6837;&#x7684;&#xFF1A;<br/>&#x590D;&#x5236;&#x5185;&#x5BB9;&#x5230;&#x526A;&#x8D34;&#x677F; &#x7A0B;&#x5E8F;&#x4EE3;&#x7801;public class Logger<br/>{<br/>&nbsp;&nbsp;private AddMessageEventHandler _Log;<br/>&nbsp;&nbsp;public event AddMessageEventHandler Log<br/>&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;add<br/>&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_Log = _Log + value;<br/>&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;remove<br/>&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_Log = _Log - value;<br/>&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;public void AddMsg (int priority, string msg)<br/>&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;AddMessageEventHandler l = _Log;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (l != null)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;l (null, new LoggerEventArgs (priority, msg));<br/>&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;}<br/>}<br/>C#&#x7F16;&#x8BD1;&#x5668;&#x521B;&#x5EFA;Add&#x548C;Remove&#x64CD;&#x4F5C;&#x6765;&#x8BBF;&#x95EE;&#x4E8B;&#x4EF6;&#x3002;&#x770B;&#x5230;&#x4E86;&#x5417;&#xFF0C;&#x516C;&#x5171;&#x7684;&#x4E8B;&#x4EF6;&#x5B9A;&#x4E49;&#x8BED;&#x8A00;&#x5F88;&#x7B80;&#x6D01;&#xFF0C;&#x6613;&#x4E8E;&#x9605;&#x8BFB;&#x548C;&#x7EF4;&#x62A4;&#xFF0C;&#x800C;&#x4E14;&#x66F4;&#x51C6;&#x786E;&#x3002;&#x5F53;&#x4F60;&#x5728;&#x7C7B;&#x4E2D;&#x6DFB;&#x52A0;&#x4E00;&#x4E2A;&#x4E8B;&#x4EF6;&#x65F6;&#xFF0C;&#x4F60;&#x5C31;&#x8BA9;&#x7F16;&#x8BD1;&#x5668;&#x53EF;&#x4EE5;&#x521B;&#x5EFA;&#x6DFB;&#x52A0;&#x548C;&#x79FB;&#x9664;&#x5C5E;&#x6027;&#x3002;&#x4F60;&#x53EF;&#x4EE5;&#xFF0C;&#x800C;&#x4E14;&#x4E5F;&#x5E94;&#x8BE5;&#xFF0C;&#x5728;&#x6709;&#x539F;&#x5219;&#x8981;&#x5F3A;&#x5236;&#x6DFB;&#x52A0;&#x65F6;&#x81EA;&#x5DF1;&#x624B;&#x52A8;&#x7684;&#x5199;&#x8FD9;&#x4E9B;&#x53E5;&#x67C4;&#x3002;<br/>&#x4E8B;&#x4EF6;&#x4E0D;&#x5FC5;&#x77E5;&#x9053;&#x53EF;&#x80FD;&#x6210;&#x4E3A;&#x76D1;&#x542C;&#x8005;&#x7684;&#x4EFB;&#x4F55;&#x8D44;&#x6599;&#xFF0C;&#x4E0B;&#x9762;&#x8FD9;&#x4E2A;&#x7C7B;&#x81EA;&#x52A8;&#x628A;&#x6240;&#x6709;&#x7684;&#x6D88;&#x606F;&#x53D1;&#x9001;&#x5230;&#x6807;&#x51C6;&#x7684;&#x9519;&#x8BEF;&#x8BBE;&#x5907;(&#x63A7;&#x5236;&#x53F0;)&#x4E0A;&#xFF1A;<br/>&#x590D;&#x5236;&#x5185;&#x5BB9;&#x5230;&#x526A;&#x8D34;&#x677F; &#x7A0B;&#x5E8F;&#x4EE3;&#x7801;class ConsoleLogger<br/>{<br/>&nbsp;&nbsp;static ConsoleLogger()<br/>&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;logger.Log += new AddMessageEventHandler( Logger_Log );<br/>&nbsp;&nbsp;}<br/>&nbsp;&nbsp;private static void Logger_Log( object sender,<br/>&nbsp;&nbsp;&nbsp;&nbsp;LoggerEventArgs msg )<br/>&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;Console.Error.WriteLine( &#34;{0}:\t{1}&#34;,<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;msg.Priority.ToString(),<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;msg.Message );<br/>&nbsp;&nbsp;}<br/>}<br/>&#x53E6;&#x4E00;&#x4E2A;&#x7C7B;&#x53EF;&#x4EE5;&#x76F4;&#x63A5;&#x8F93;&#x51FA;&#x5230;&#x7CFB;&#x7EDF;&#x4E8B;&#x4EF6;&#x65E5;&#x5FD7;&#xFF1A;<br/>&#x590D;&#x5236;&#x5185;&#x5BB9;&#x5230;&#x526A;&#x8D34;&#x677F; &#x7A0B;&#x5E8F;&#x4EE3;&#x7801;class EventLogger<br/>{<br/>&nbsp;&nbsp;private static string eventSource;<br/>&nbsp;&nbsp;private static EventLog logDest;<br/>&nbsp;&nbsp;static EventLogger()<br/>&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;logger.Log +=new AddMessageEventHandler( Event_Log );<br/>&nbsp;&nbsp;}<br/>&nbsp;&nbsp;public static string EventSource<br/>&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;get<br/>&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return eventSource;<br/>&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;set<br/>&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;eventSource = value;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if ( ! EventLog.SourceExists( eventSource ) )<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;EventLog.Cr&#101;ateEventSource( eventSource,<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#34;ApplicationEventLogger&#34; );<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if ( logDest != null )<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logDest.Dispose( );<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logDest = new EventLog( );<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logDest.Source = eventSource;<br/>&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;}<br/>&nbsp;&nbsp;private static void Event_Log( object sender,<br/>&nbsp;&nbsp;&nbsp;&nbsp;LoggerEventArgs msg )<br/>&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;if ( logDest != null )<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logDest.WriteEntry( msg.Message,<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;EventLogEntryType.Information,<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;msg.Priority );<br/>&nbsp;&nbsp;}<br/>}<br/>&#x4E8B;&#x4EF6;&#x4F1A;&#x5728;&#x53D1;&#x751F;&#x4E00;&#x4E9B;&#x4E8B;&#x60C5;&#x65F6;&#xFF0C;&#x901A;&#x77E5;&#x4EFB;&#x610F;&#x591A;&#x4E2A;&#x5BF9;&#x6D88;&#x606F;&#x611F;&#x5174;&#x8DA3;&#x7684;&#x5BA2;&#x6237;&#x3002;Logger&#x7C7B;&#x4E0D;&#x5FC5;&#x9884;&#x5148;&#x77E5;&#x9053;&#x4EFB;&#x4F55;&#x5BF9;&#x6D88;&#x606F;&#x611F;&#x5174;&#x8DA3;&#x7684;&#x5BF9;&#x8C61;&#x3002;<br/>Logger&#x7C7B;&#x53EA;&#x5305;&#x542B;&#x4E00;&#x4E2A;&#x4E8B;&#x4EF6;&#x3002;&#x5927;&#x591A;&#x6570;windows&#x63A7;&#x4EF6;&#x6709;&#x5F88;&#x591A;&#x4E8B;&#x4EF6;&#xFF0C;&#x5728;&#x8FD9;&#x79CD;&#x60C5;&#x51B5;&#x4E0B;&#xFF0C;&#x4E3A;&#x6BCF;&#x4E00;&#x4E2A;&#x4E8B;&#x4EF6;&#x6DFB;&#x52A0;&#x4E00;&#x4E2A;&#x5B57;&#x6BB5;&#x5E76;&#x4E0D;&#x662F;&#x4E00;&#x4E2A;&#x53EF;&#x4EE5;&#x63A5;&#x53D7;&#x7684;&#x65B9;&#x6CD5;&#x3002;&#x5728;&#x67D0;&#x4E9B;&#x60C5;&#x51B5;&#x4E0B;&#xFF0C;&#x4E00;&#x4E2A;&#x7A0B;&#x5E8F;&#x4E2D;&#x53EA;&#x5B9E;&#x9645;&#x4E0A;&#x53EA;&#x5B9A;&#x4E49;&#x4E86;&#x5C11;&#x91CF;&#x7684;&#x4E8B;&#x4EF6;&#x3002;&#x5F53;&#x4F60;&#x9047;&#x5230;&#x8FD9;&#x79CD;&#x60C5;&#x51B5;&#x65F6;&#xFF0C;&#x4F60;&#x53EF;&#x4EE5;&#x4FEE;&#x6539;&#x8BBE;&#x8BA1;&#xFF0C;&#x53EA;&#x6709;&#x5728;&#x8FD0;&#x884C;&#x65F6;&#x987B;&#x8981;&#x4E8B;&#x4EF6;&#x65F6;&#x5728;&#x521B;&#x5EFA;&#x5B83;&#x3002;<br/>(&#x8BD1;&#x6CE8;&#xFF1A;&#x4F5C;&#x8005;&#x7684;&#x4E00;&#x4E2A;&#x660E;&#x663E;&#x76F8;&#x601D;&#x5C31;&#x662F;&#xFF0C;&#x5F53;&#x4ED6;&#x60F3;&#x8BF4;&#x4EC0;&#x4E48;&#x597D;&#x65F6;&#xFF0C;&#x5C31;&#x51B3;&#x4E0D;&#x4F1A;&#xFF0C;&#x6216;&#x8005;&#x5F88;&#x5C11;&#x8BF4;&#x8FD9;&#x4E2A;&#x4E8B;&#x60C5;&#x7684;&#x8D1F;&#x9762;&#x5F71;&#x54CD;&#x3002;&#x5176;&#x5B9E;&#x4E8B;&#x4EF6;&#x5BF9;&#x6027;&#x80FD;&#x7684;&#x5F71;&#x54CD;&#x662F;&#x5F88;&#x5927;&#x7684;&#xFF0C;&#x5E94;&#x8BE5;&#x5C3D;&#x91CF;&#x5C11;&#x7528;&#x3002;&#x4E8B;&#x4EF6;&#x7ED9;&#x6211;&#x4EEC;&#x5E26;&#x6765;&#x7684;&#x597D;&#x5904;&#x662F;&#x5F88;&#x591A;&#x7684;&#xFF0C;&#x4F46;&#x4E0D;&#x8981;&#x6D77;&#x6EE5;&#x7528;&#x4E8B;&#x4EF6;&#x3002;&#x4F5C;&#x8005;&#x5728;&#x8FD9;&#x91CC;&#x6CA1;&#x6709;&#x660E;&#x8BF4;&#x4E8B;&#x4EF6;&#x7684;&#x8D1F;&#x9762;&#x5F71;&#x54CD;&#x3002;)<br/>&#x6269;&#x5C55;&#x7684;Logger&#x7C7B;&#x6709;&#x4E00;&#x4E2A;System.ComponentModel.EventHandlerList&#x5BB9;&#x5668;&#xFF0C;&#x5B83;&#x5B58;&#x50A8;&#x4E86;&#x5728;&#x7ED9;&#x5B9A;&#x7CFB;&#x7EDF;&#x4E2D;&#x5E94;&#x8BE5;&#x5F15;&#x53D1;&#x7684;&#x4E8B;&#x4EF6;&#x5BF9;&#x8C61;&#x3002;&#x66F4;&#x65B0;&#x7684;AddMsg()&#x65B9;&#x6CD5;&#x73B0;&#x5728;&#x5E26;&#x4E00;&#x4E2A;&#x53C2;&#x6570;&#xFF0C;&#x5B83;&#x53EF;&#x4EE5;&#x8BE6;&#x7EC6;&#x7684;&#x6307;&#x793A;&#x5B50;&#x7CFB;&#x7EDF;&#x65E5;&#x5FD7;&#x7684;&#x6D88;&#x606F;&#x3002;&#x5982;&#x679C;&#x5B50;&#x7CFB;&#x7EDF;&#x6709;&#x4EFB;&#x4F55;&#x7684;&#x76D1;&#x542C;&#x8005;&#xFF0C;&#x4E8B;&#x4EF6;&#x5C31;&#x88AB;&#x5F15;&#x53D1;&#x3002;&#x540C;&#x6837;&#xFF0C;&#x5982;&#x679C;&#x4E8B;&#x4EF6;&#x7684;&#x76D1;&#x542C;&#x8005;&#x5728;&#x6240;&#x6709;&#x611F;&#x5174;&#x8DA3;&#x7684;&#x6D88;&#x606F;&#x4E0A;&#x76D1;&#x542C;&#xFF0C;&#x5B83;&#x540C;&#x6837;&#x4F1A;&#x88AB;&#x5F15;&#x53D1;&#xFF1A;<br/>&#x590D;&#x5236;&#x5185;&#x5BB9;&#x5230;&#x526A;&#x8D34;&#x677F; &#x7A0B;&#x5E8F;&#x4EE3;&#x7801;public class Logger<br/>{<br/>&nbsp;&nbsp;private static System.ComponentModel.EventHandlerList<br/>&nbsp;&nbsp;&nbsp;&nbsp;Handlers = new System.ComponentModel.EventHandlerList();<br/>&nbsp;&nbsp;static public void AddLogger(<br/>&nbsp;&nbsp;&nbsp;&nbsp;string system, AddMessageEventHandler ev )<br/>&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;Handlers[ system ] = ev;<br/>&nbsp;&nbsp;}<br/>&nbsp;&nbsp;static public void RemoveLogger( string system )<br/>&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;Handlers[ system ] = null;<br/>&nbsp;&nbsp;}<br/>&nbsp;&nbsp;static public void AddMsg ( string system,<br/>&nbsp;&nbsp;&nbsp;&nbsp;int priority,&nbsp;&nbsp;string msg )<br/>&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;if ( ( system != null ) &amp;&amp; ( system.Length &gt; 0 ) )<br/>&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;AddMessageEventHandler l =<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Handlers[ system ] as AddMessageEventHandler;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LoggerEventArgs args = new LoggerEventArgs(<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;priority, msg );<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if ( l != null )<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;l ( null, args );<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// The empty string means receive all messages:<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;l = Handlers[ &#34;&#34; ] as AddMessageEventHandler;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if ( l != null )<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;l( null, args );<br/>&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;}<br/>}<br/>&#x8FD9;&#x4E2A;&#x65B0;&#x7684;&#x4F8B;&#x5B50;&#x5728;Event HandlerList&#x96C6;&#x5408;&#x4E2D;&#x5B58;&#x50A8;&#x4E86;&#x4E2A;&#x522B;&#x7684;&#x4E8B;&#x4EF6;&#x53E5;&#x67C4;&#xFF0C;&#x5BA2;&#x6237;&#x4EE3;&#x7801;&#x6DFB;&#x52A0;&#x5230;&#x7279;&#x6B8A;&#x7684;&#x5B50;&#x7CFB;&#x7EDF;&#x4E2D;&#xFF0C;&#x800C;&#x4E14;&#x65B0;&#x7684;&#x4E8B;&#x4EF6;&#x5BF9;&#x8C61;&#x88AB;&#x521B;&#x5EFA;&#x3002;&#x7136;&#x540E;&#x540C;&#x6837;&#x7684;&#x5B50;&#x7CFB;&#x7EDF;&#x9700;&#x8981;&#x65F6;&#xFF0C;&#x53D6;&#x56DE;&#x540C;&#x6837;&#x7684;&#x4E8B;&#x4EF6;&#x5BF9;&#x8C61;&#x3002;&#x5982;&#x679C;&#x4F60;&#x5F00;&#x53D1;&#x4E00;&#x4E2A;&#x7C7B;&#x5305;&#x542B;&#x6709;&#x5927;&#x91CF;&#x7684;&#x4E8B;&#x4EF6;&#x5B9E;&#x4F8B;&#xFF0C;&#x4F60;&#x5E94;&#x8BE5;&#x8003;&#x8651;&#x4F7F;&#x7528;&#x4E8B;&#x4EF6;&#x53E5;&#x67C4;&#x96C6;&#x5408;&#x3002;&#x5F53;&#x5BA2;&#x6237;&#x9644;&#x52A0;&#x4E8B;&#x4EF6;&#x53E5;&#x67C4;&#x65F6;&#xFF0C;&#x4F60;&#x53EF;&#x4EE5;&#x9009;&#x62E9;&#x521B;&#x5EFA;&#x4E8B;&#x4EF6;&#x6210;&#x5458;&#x3002;&#x5728;.Net&#x6846;&#x67B6;&#x5185;&#x90E8;&#xFF0C;System.Windows.Forms.Control&#x7C7B;&#x5BF9;&#x4E8B;&#x4EF6;&#x4F7F;&#x7528;&#x4E86;&#x4E00;&#x4E2A;&#x590D;&#x6742;&#x4E14;&#x53D8;&#x5411;&#x7684;&#x5B9E;&#x73B0;&#xFF0C;&#x4ECE;&#x800C;&#x9690;&#x85CF;&#x4E86;&#x590D;&#x6742;&#x7684;&#x4E8B;&#x4EF6;&#x6210;&#x5458;&#x5B57;&#x6BB5;&#x3002;&#x6BCF;&#x4E00;&#x4E2A;&#x4E8B;&#x4EF6;&#x5B57;&#x6BB5;&#x5728;&#x5185;&#x90E8;&#x662F;&#x901A;&#x8FC7;&#x8BBF;&#x95EE;&#x96C6;&#x5408;&#x6765;&#x6DFB;&#x52A0;&#x548C;&#x79FB;&#x9664;&#x5B9E;&#x9645;&#x7684;&#x53E5;&#x67C4;&#x3002;&#x5173;&#x4E8E;C#&#x8BED;&#x8A00;&#x7684;&#x8FD9;&#x4E00;&#x7279;&#x6B8A;&#x4E60;&#x60EF;&#xFF0C;&#x4F60;&#x53EF;&#x4EE5;&#x5728;&#x539F;&#x5219;49&#x4E2D;&#x53D1;&#x73B0;&#x66F4;&#x591A;&#x7684;&#x4FE1;&#x606F;&#x3002;<br/>&#x4F60;&#x7528;&#x4E8B;&#x4EF6;&#x5728;&#x7C7B;&#x4E0A;&#x5B9A;&#x4E49;&#x4E86;&#x4E00;&#x4E2A;&#x5916;&#x63A5;&#x7684;&#x63A5;&#x53E3;&#xFF1A;&#x4EFB;&#x610F;&#x6570;&#x91CF;&#x7684;&#x5BA2;&#x6237;&#x53EF;&#x4EE5;&#x6DFB;&#x52A0;&#x53E5;&#x67C4;&#x5230;&#x4E8B;&#x4EF6;&#x4E0A;&#xFF0C;&#x800C;&#x4E14;&#x5904;&#x7406;&#x5B83;&#x4EEC;&#x3002;&#x8FD9;&#x4E9B;&#x5BF9;&#x8C61;&#x5728;&#x7F16;&#x8BD1;&#x65F6;&#x4E0D;&#x5FC5;&#x77E5;&#x9053;&#x662F;&#x8C01;&#x3002;&#x4E8B;&#x4EF6;&#x7CFB;&#x7EDF;&#x4E5F;&#x4E0D;&#x5FC5;&#x77E5;&#x9053;&#x8BE6;&#x7EC6;&#x5C31;&#x53EF;&#x4EE5;&#x5408;&#x7406;&#x7684;&#x4F7F;&#x7528;&#x5B83;&#x4EEC;&#x3002;&#x5728;C#&#x4E2D;&#x4E8B;&#x4EF6;&#x53EF;&#x4EE5;&#x51CF;&#x5F31;&#x6D88;&#x606F;&#x7684;&#x53D1;&#x9001;&#x8005;&#x548C;&#x53EF;&#x80FD;&#x7684;&#x6D88;&#x606F;&#x63A5;&#x53D7;&#x8005;&#x4E4B;&#x95F4;&#x7684;&#x5173;&#x7CFB;&#xFF0C;&#x53D1;&#x9001;&#x8005;&#x53EF;&#x4EE5;&#x8BBE;&#x8BA1;&#x6210;&#x4E0E;&#x63A5;&#x53D7;&#x8005;&#x65E0;&#x5173;&#x3002;&#x4E8B;&#x4EF6;&#x662F;&#x7C7B;&#x578B;&#x628A;&#x52A8;&#x4F5C;&#x4FE1;&#x606F;&#x53D1;&#x5E03;&#x51FA;&#x53BB;&#x7684;&#x6807;&#x51C6;&#x65B9;&#x6CD5;&#x3002;<br/>========================================================&nbsp;&nbsp;&nbsp;&nbsp;<br/>Item 22: Define Outgoing Interfaces with Events<br/>Events define the outgoing interface for your type. Events are built on delegates to provide type-safe function signatures for event handlers. Add to this the fact that most examples that use delegates are events, and developers start thinking that events and delegates are the same things. In Item 21, I showed you examples of when you can use delegates without defining events. You should raise events when your type must communicate with multiple clients to inform them of actions in the system.<br/>Consider a simple example. You&#39;re building a log class that acts as a dispatcher of all messages in an application. It will accept all messages from sources in your application and will dispatch those messages to any interested listeners. These listeners might be attached to the console, a database, the system log, o&#114; some other mechanism. You define the class as follows, to raise one event whenever a message arrives:<br/>&#x590D;&#x5236;&#x5185;&#x5BB9;&#x5230;&#x526A;&#x8D34;&#x677F; &#x7A0B;&#x5E8F;&#x4EE3;&#x7801;public class LoggerEventArgs : EventArgs<br/>{<br/>&nbsp;&nbsp;public readonly string Message;<br/>&nbsp;&nbsp;public readonly int Priority;<br/>&nbsp;&nbsp;public LoggerEventArgs ( int p, string m )<br/>&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;Priority = p;<br/>&nbsp;&nbsp;&nbsp;&nbsp;Message = m;<br/>&nbsp;&nbsp;}<br/>}<br/>// Define the signature for the event handler:<br/>public delegate void AddMessageEventHandler( object sender,<br/>&nbsp;&nbsp;LoggerEventArgs msg );<br/>public class Logger<br/>{<br/>&nbsp;&nbsp;static Logger( )<br/>&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;_theOnly = new Logger( );<br/>&nbsp;&nbsp;}<br/>&nbsp;&nbsp;private Logger( )<br/>&nbsp;&nbsp;{<br/>&nbsp;&nbsp;}<br/>&nbsp;&nbsp;private static Logger _theOnly = null;<br/>&nbsp;&nbsp;public Logger Singleton<br/>&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;get<br/>&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return _theOnly;<br/>&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;}<br/>&nbsp;&nbsp;// Define the event:<br/>&nbsp;&nbsp;public event AddMessageEventHandler Log;<br/>&nbsp;&nbsp;// add a message, and log it.<br/>&nbsp;&nbsp;public void AddMsg ( int priority, string msg )<br/>&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;// This idiom discussed below.<br/>&nbsp;&nbsp;&nbsp;&nbsp;AddMessageEventHandler l = Log;<br/>&nbsp;&nbsp;&nbsp;&nbsp;if ( l != null )<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;l ( null, new LoggerEventArgs( priority, msg ) );<br/>&nbsp;&nbsp;}<br/>}<br/>The AddMsg method showsthe proper way to raise events. The temporary variable to reference the log event handler is an important safeguard against race conditions in multithreaded programs. Without the copy of the reference, clients could remove event handlers between the if statement check and the execution of the event handler. By copying the reference, that can&#39;t happen.<br/>I&#39;ve defined LoggerEventArgs to hold the priority of an event and the message. The delegate defines the signature for the event handler. Inside the Logger class, the event field defines the event handler. The compiler sees the public event field definition and cr&#101;ates the Add and Remove operators for you. The generated code is exactly the same as though you had written the following:<br/>&#x590D;&#x5236;&#x5185;&#x5BB9;&#x5230;&#x526A;&#x8D34;&#x677F; &#x7A0B;&#x5E8F;&#x4EE3;&#x7801;public class Logger<br/>{<br/>&nbsp;&nbsp;private AddMessageEventHandler _Log;<br/>&nbsp;&nbsp;public event AddMessageEventHandler Log<br/>&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;add<br/>&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_Log = _Log + value;<br/>&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;remove<br/>&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_Log = _Log - value;<br/>&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;public void AddMsg (int priority, string msg)<br/>&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;AddMessageEventHandler l = _Log;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (l != null)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;l (null, new LoggerEventArgs (priority, msg));<br/>&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;}<br/>}<br/>The C# compiler cr&#101;ates the add and remove accessors for the event. I find the public event declaration language more concise, easier to read and maintain, and more correct. When you cr&#101;ate events in your class, declare public events and let the compiler cr&#101;ate the add and remove properties for you. You can and should write these handlers yourself when you have additional rules to enforce.<br/>Events do not need to have any knowledge about the potential listeners. The following class automatically routes all messages to the Standard Error console:<br/>&#x590D;&#x5236;&#x5185;&#x5BB9;&#x5230;&#x526A;&#x8D34;&#x677F; &#x7A0B;&#x5E8F;&#x4EE3;&#x7801;class ConsoleLogger<br/>{<br/>&nbsp;&nbsp;static ConsoleLogger()<br/>&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;logger.Log += new AddMessageEventHandler( Logger_Log );<br/>&nbsp;&nbsp;}<br/>&nbsp;&nbsp;private static void Logger_Log( object sender,<br/>&nbsp;&nbsp;&nbsp;&nbsp;LoggerEventArgs msg )<br/>&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;Console.Error.WriteLine( &#34;{0}:\t{1}&#34;,<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;msg.Priority.ToString(),<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;msg.Message );<br/>&nbsp;&nbsp;}<br/>}<br/>Another class could direct output to the system event log:<br/>&#x590D;&#x5236;&#x5185;&#x5BB9;&#x5230;&#x526A;&#x8D34;&#x677F; &#x7A0B;&#x5E8F;&#x4EE3;&#x7801;class EventLogger<br/>{<br/>&nbsp;&nbsp;private static string eventSource;<br/>&nbsp;&nbsp;private static EventLog logDest;<br/>&nbsp;&nbsp;static EventLogger()<br/>&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;logger.Log +=new AddMessageEventHandler( Event_Log );<br/>&nbsp;&nbsp;}<br/>&nbsp;&nbsp;public static string EventSource<br/>&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;get<br/>&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return eventSource;<br/>&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;set<br/>&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;eventSource = value;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if ( ! EventLog.SourceExists( eventSource ) )<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;EventLog.Cr&#101;ateEventSource( eventSource,<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#34;ApplicationEventLogger&#34; );<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if ( logDest != null )<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logDest.Dispose( );<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logDest = new EventLog( );<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logDest.Source = eventSource;<br/>&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;}<br/>&nbsp;&nbsp;private static void Event_Log( object sender,<br/>&nbsp;&nbsp;&nbsp;&nbsp;LoggerEventArgs msg )<br/>&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;if ( logDest != null )<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logDest.WriteEntry( msg.Message,<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;EventLogEntryType.Information,<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;msg.Priority );<br/>&nbsp;&nbsp;}<br/>}<br/>Events notify any number of interested clients that something happened. The Logger class does not need any prior knowledge of which objects are interested in logging events.<br/>The Logger class contained only one event. There are classes (mostly Windows controls) that have very large numbers of events. In those cases, the idea of using one field per event might be unacceptable. In some cases, only a small number of the defined events is actually used in any one application. When you encounter that situation, you can modify the design to cr&#101;ate the event objects only when needed at runtime.<br/>The core framework contains examples of how to do this in the Windows control subsystem. To show you how, add subsystems to the Logger class. You cr&#101;ate an event for each subsystem. Clients register on the event that is pertinent to their subsystem.<br/>The extended Logger class has a System.ComponentModel.EventHandlerList container that stores all the event objects that should be raised for a given system. The up&#100;ated AddMsg() method now takes a string parameter that specifies the subsystem generating the log message. If the subsystem has any listeners, the event gets raised. Also, if an event listener has registered an interest in all messages, its event gets raised:<br/>&#x590D;&#x5236;&#x5185;&#x5BB9;&#x5230;&#x526A;&#x8D34;&#x677F; &#x7A0B;&#x5E8F;&#x4EE3;&#x7801;public class Logger<br/>{<br/>&nbsp;&nbsp;private static System.ComponentModel.EventHandlerList<br/>&nbsp;&nbsp;&nbsp;&nbsp;Handlers = new System.ComponentModel.EventHandlerList();<br/>&nbsp;&nbsp;static public void AddLogger(<br/>&nbsp;&nbsp;&nbsp;&nbsp;string system, AddMessageEventHandler ev )<br/>&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;Handlers[ system ] = ev;<br/>&nbsp;&nbsp;}<br/>&nbsp;&nbsp;static public void RemoveLogger( string system )<br/>&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;Handlers[ system ] = null;<br/>&nbsp;&nbsp;}<br/>&nbsp;&nbsp;static public void AddMsg ( string system,<br/>&nbsp;&nbsp;&nbsp;&nbsp;int priority,&nbsp;&nbsp;string msg )<br/>&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;if ( ( system != null ) &amp;&amp; ( system.Length &gt; 0 ) )<br/>&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;AddMessageEventHandler l =<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Handlers[ system ] as AddMessageEventHandler;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LoggerEventArgs args = new LoggerEventArgs(<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;priority, msg );<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if ( l != null )<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;l ( null, args );<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// The empty string means receive all messages:<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;l = Handlers[ &#34;&#34; ] as AddMessageEventHandler;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if ( l != null )<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;l( null, args );<br/>&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;}<br/>}<br/>This new example stores the individual event handlers in the Event HandlerList collection. Client code attaches to a specific subsystem, and a new event object is cr&#101;ated. Subsequent requests for the same subsystem retrieve the same event object. If you develop a class that contains a large number of events in its interface, you should consider using this collection of event handlers. You cr&#101;ate event members when clients attach to the event handler on their choice. Inside the .NET Framework, the System.Windows.Forms.Control class uses a more complicated variation of this implementation to hide the complexity of all its event fields. Each event field internally accesses a collection of objects to add and remove the particular handlers. You can find more information that shows this idiom in the C# language specification (see Item 49).<br/>You define outgoing interfaces in classes with events: Any number of clients can attach handlers to the events and process them. Those clients need not be known at compile time. Events don&#39;t need subscribers for the system to function properly. Using events in C# decouples the sender and the possible receivers of notifications. The sender can be developed completely independently of any receivers. Events are the standard way to broadcast information about actions that your type has taken.</p><p> + <a href="#CommentCard">&#x67E5;&#x770B;&#x5F53;&#x524D;&#x65E5;&#x5FD7;&#x8BC4;&#x8BBA;</a> (0)</p><p>&nbsp;<br/><br/><a href="wap.asp?do=Login">&#x767B;&#x5F55;</a></p><p><br/>&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;</p><p><a href="wap.asp">&#x6728;&#x5B50;&#x5C4B;</a></p><p><a href="http://www.pjhome.net/wap.asp">PJBlog3&nbsp;v3.2.9.518</a>&nbsp;Inside.</p><p>Processed&nbsp;In&nbsp;0.113&nbsp;ms</p><do type="prev" label="&#x8FD4;&#x56DE;"><prev/></do></card><card id="postCommentCard"><p><b>&#x6807;&#x9898;&#x3A;</b> <a href="#MainCard">&#x45;&#x66;&#x66;&#x65;&#x63;&#x74;&#x69;&#x76;&#x65;&#x20;&#x43;&#x23;&#x20;&#x539F;&#x5219;&#x32;&#x32;&#xFF1A;&#x7528;&#x4E8B;&#x4EF6;&#x5B9A;&#x4E49;&#x5BF9;&#x5916;&#x63A5;&#x53E3;</a></p><p><br/>你没有权限发表评论</p><p><br/>&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;</p><p><a href="wap.asp">&#x6728;&#x5B50;&#x5C4B;</a></p><p><a href="http://www.pjhome.net/wap.asp">PJBlog3&nbsp;v3.2.9.518</a>&nbsp;Inside.</p><p>Processed&nbsp;In&nbsp;0.113&nbsp;ms</p><do type="prev" label="&#x8FD4;&#x56DE;"><prev/></do></card><card id="CommentCard"><p>&#x6682;&#x65E0;&#x8BC4;&#x8BBA;</p><p><a href="#MainCard">&#x8FD4;&#x56DE;</a></p><p><br/>&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;</p><p><a href="wap.asp">&#x6728;&#x5B50;&#x5C4B;</a></p><p><a href="http://www.pjhome.net/wap.asp">PJBlog3&nbsp;v3.2.9.518</a>&nbsp;Inside.</p><p>Processed&nbsp;In&nbsp;0.113&nbsp;ms</p><do type="prev" label="&#x8FD4;&#x56DE;"><prev/></do></card>
</wml>
