|
| |
名片设计 CorelDRAW Illustrator AuotoCAD Painter 其他软件 Photoshop Fireworks Flash |
|
Using Delegates and Events If you are familiar with Windows programming, you’ve most likely dealt with callbacks. Callbacks are method calls that are executed when some event happens http://www.syngress.com.70 Chapter 2 • Introducing C# Programming during processing. For instance, a callback can be established to handle the pro-cessing of an incoming message on a communications port. Another part of the communications program can wait for messages on a communications port and invoke the callback whenever a new message arrives. Function pointers perform the same sort of tasks in straight C/C++ programs. Delegates in C# improve on method callbacks in two areas. Delegates are type safe, unlike callbacks in Windows programming. In addition, delegates can call more than one callback when an event occurs. This is termed multicasting. Delegates Let’s extend our employees sample to use delegates.This sample simulates a back-ground process that receives messages to add new employees to the employee list. Our queue will be a static array, but in the real world it could be a message queue (Microsoft Message Queue [MSMQ]), a socket, or some other type of queue. The source code in Figure 2.7 shows the relevant portions of the sample pertaining to delegates.The full source code for this sample is on the CD in the file Delegates.cs. Figure 2.7 Relevant Portions of the Delegates.cs Program Listing using System; using System.Collections; /// <summary> /// Contains the program entry point for the Delegates Sample. /// </summary> class DelegatesSample { static void Main( string[] args ) { try { // Create a container to hold employees Employees employees = new Employees(4); // Create and drain our simulated message queue EmployeeQueueMonitor monitor = http://www.syngress.com Continued.Introducing C# Programming • Chapter 2 71 new EmployeeQueueMonitor( employees ); monitor.start(); monitor.stop(); // Display the employee list on screen Console.WriteLine( "List of employees added via delegate:" ); foreach ( Employee employee in employees ) { string name = employee.FirstName + " " + employee.MiddleName + " " + employee.LastName; string ssn = employee.SSN; Console.WriteLine( "Name: {0}, SSN: {1}", name, ssn ); } } catch ( Exception exception ) { // Display any errors on screen Console.WriteLine( exception.Message ); } } } /// <summary> /// Simulates our message queue. /// </summary> class EmployeeQueueMonitor { // Delegate signature http://www.syngress.com Figure 2.7 Continued Continued.72 Chapter 2 • Introducing C# Programming public delegate void AddEventCallback( string FirstName, string LastName, string MiddleName, string SSN ); // Instance of the delegate private AddEventCallback m_addEventCallback; private Employees m_employees; private int m_lengthQueue; private string[, ] m_msgQueue = { {"Timothy", "Arthur", "Tucker", "555-55-5555"}, {"Sally", "Bess", "Jones", "666-66-6666" }, {"Jeff", "Michael", "Simms", "777-77-7777"}, {"Janice", "Anne", "Best", "888-88-8888" } }; public EmployeeQueueMonitor( Employees employees ) { m_employees = employees; m_lengthQueue = 4; // Create an instace of the delegate and register the // addEmployee method of this class as a callback. m_addEventCallback = new AddEventCallback( this.addEmployee ); } // Drain the queue. public void start() { if ( m_employees == null ) return; http://www.syngress.com Figure 2.7 Continued Continued.Introducing C# Programming • Chapter 2 73 for ( int i = 0; i < m_lengthQueue; i++ ) { string FirstName = m_msgQueue[i,0]; string MiddleName = m_msgQueue[i,1]; string LastName = m_msgQueue[i,2]; string SSN = m_msgQueue[i,3]; // Invoke the callback registered with the delegate Console.WriteLine( "Invoking delegate" ); m_addEventCallback( FirstName, LastName, MiddleName, SSN ); } } public void stop() { // In a real communications program you would shut down // gracefully. } // Called by the delegate when a message to add an employee // is read from the message queue. public void addEmployee( string FirstName, string MiddleName, string LastName, string SSN ) { Console.WriteLine( "In delegate, adding employee/r/n" ); int index = m_employees.Length; m_employees[index] = new Employee ( FirstName, MiddleName, LastName, SSN ); } } http://www.syngress.com Figure 2.7 Continued.74 Chapter 2 • Introducing C# Programming Single Cast The source code in the previous section is an example of a single cast delegate. A single cast delegate invokes only one callback method. Let’s examine our previous sample to see this. The EmployeeQueueMonitor class simulates a message queue. It contains a static array that holds the current messages. At the top of EmployeeQueueMonitor are the following lines: public delegate void AddEventCallback( string FirstName, string LastName, string MiddleName, string SSN ); private AddEventCallback m_addEventCallback; The first statement defines a delegate and the parameters an object instance of the delegate takes. In this case, we callback to a method that takes first name, last name, middle name, and SSN. We do this whenever a request to add a new employee appears in the message queue. The second statement declares a member variable to hold our delegate. It is initially set to null. A new object instance must be created prior to making method calls through the delegate. An object instance is instantiated in the con-structor of EmployeeQueueMonitor. m_addEventCallback = new AddEventCallback( this.addEmployee ); This statement creates a new object instance of the delegate. The delegate takes as an argument the method to call when the delegate is invoked. In this case, whenever the delegate is invoked, the method that will execute is EmployeeQueueMonitor.addEmployee. In the start method of EmployeeQueueMonitor is the following code: for ( int i = 0; i < m_lengthQueue; i++ ) { string FirstName = m_msgQueue[i,0]; string MiddleName = m_msgQueue[i,1]; string LastName = m_msgQueue[i,2]; string SSN = m_msgQueue[i,3]; // Invoke the callback registered with the delegate Console.WriteLine( "Invoking delegate" ); http://www.syngress.com.Introducing C# Programming • Chapter 2 75 m_addEventCallback( FirstName, LastName, MiddleName, SSN ); } This code simulates draining the message queue of any waiting messages.The callback function is invoked by treating the m_addEventCallback member variable as if it were a method call passing it our four parameters. Note that you do not specify the callback itself when making the call.The delegate maintains the address of the callback internally and therefore knows the method to call.The following example shows what not to do: // Incorrect m_addEventCallback.addEmployee( FirstName, LastName, MiddleName, SSN ); Multicast The true power of delegates becomes apparent when discussing multicast dele-gates. Let’s extend our previous example a bit further. Because background pro-cesses do not usually have a user interface for human interaction, they typically log incoming events for later review. Let’s add a second callback to our sample to log incoming add employee requests.The relevant snippets of code are shown in Figure 2.8.The full source code is for this sample is on the CD in the file Multicasting.cs. Figure 2.8 Relevant Portions of the Multicasting.cs Program Listing class EmployeeQueueMonitor { // Delegate signature for add employee event callback public delegate void AddEventCallback( string FirstName, string LastName, string MiddleName, string SSN ); // Instance of the delegate private AddEventCallback m_addEventCallback; private EmployeeQueueLogger m_logger; public EmployeeQueueMonitor( Employees employees ) { http://www.syngress.com Continued.76 Chapter 2 • Introducing C# Programming m_employees = employees; m_lengthQueue = 4; m_logger = new EmployeeQueueLogger( "log.txt" ); // Register the methods that the delegate will invoke when an // add employee message is read from the message queue m_addEventCallback = new AddEventCallback( this.addEmployee ); m_addEventCallback += new AddEventCallback( m_logger.logAddRequest ); } // Drain the queue. public void start() { if ( m_employees == null ) return; for ( int i = 0; i < m_lengthQueue; i++ ) { string FirstName = m_msgQueue[i,0]; string MiddleName = m_msgQueue[i,1]; string LastName = m_msgQueue[i,2]; string SSN = m_msgQueue[i,3]; Console.WriteLine( "Invoking delegate" ); // Invoke the delegate passing the data associated with // adding a new employee resulting in the subscribed // callbacks methods being executed, namely // Employees.this.addEmployee() http://www.syngress.com Figure 2.8 Continued Continued.Introducing C# Programming • Chapter 2 77 // and EmployeeQueueLogger.logAddRequest() m_addEventCallback( FirstName, LastName, MiddleName, SSN ); } } // Called by delegate whenever a new add employee message // appears in the message queue. Notice the signature matches // that requried by AddEventCallback public void addEmployee( string FirstName, string MiddleName, string LastName, string SSN ) { Console.WriteLine( "In delegate, adding employee/r/n" ); int index = m_employees.Length; m_employees[index] = new Employee ( FirstName, MiddleName, LastName, SSN ); } } /// <summary> /// Writes add employee events to a log file. /// </summary> class EmployeeQueueLogger { string m_fileName; public EmployeeQueueLogger( string fileName ) { m_fileName = fileName; } // Called by delegate whenever a new add employee message http://www.syngress.com 返回类别: 教程 上一教程: 黑客写出了针对.Net平台的反编译器 下一教程: Windows 操作系统中的 .NET Framework 支持(附录) 您可以阅读与"Using Delegates and Events 1 (来自一本49美元/817页2002年的书《C#.net web developer\'s guide》)"相关的教程: · Using Delegates and Events 2 (来自一本49美元/817页2002年的书《C#.net web developer\'s guide》) · .NET之ASP Web Form迅速入门(3) · 解决.NET(WebApplication)安装部署的不能选择安装路径的问题 · 控制VC++.NET中WEB对话框的HTML元素属性 · ASP.NET创建XML Web服务全接触(2) |
| 快精灵印艺坊 版权所有 |
首页 |
||