MethodDelegate del =
(MethodDelegate)((AsyncResult)ar).AsyncDelegate;
//---get the result---
int result = del.EndInvoke(ar);
Console.WriteLine("Result of addition is: " + result);
}
Within the ResultCallback()
method, you first obtain the delegate to the AddTwoNumbers()
method by using the AsyncDelegate
property, which returns the delegate on which the asynchronous call was invoked. You then obtain the result of the asynchronous call by using the EndInvoke()
method, passing it the IAsyncResult
variable ( ar
).
Finally, to demonstrate the asynchronous calling of the AddTwoNumbers()
method, you can insert a Sleep()
statement to delay the execution (simulating long execution):
static private int AddTwoNumbers(int num1, int num2) {
//---simulate long execution---
System.Threading.Thread.Sleep(5000);
return num1 + num2;
}
Figure 7-3 shows the output of this program.
Figure 7-3
When using asynchronous callbacks, you can make your program much more responsive by executing different parts of the program in different threads.
Chapter 10 discusses more about threading.
Anonymous Methods and Lambda Expressions
Beginning with C# 2.0, you can use a feature known as anonymous methods to define a delegate.
An anonymous method is an "inline" statement or expression that can be used as a delegate parameter. To see how it works, take a look at the following example:
class Program {
delegate void MethodsDelegate(string Message);
static void Main(string[] args) {
MethodsDelegate method = Method1;
//---call the delegated method---
method("Using delegate.");
Console.ReadLine();
}
static private void Method1(string Message) {
Console.WriteLine(Message);
}
}
Instead of defining a separate method and then using a delegate variable to point to it, you can shorten the code using an anonymous method:
class Program {
delegate void MethodsDelegate(string Message);
static void Main(string[] args) {
MethodsDelegate method = delegate(string Message) {
Console.WriteLine(Message);
};
//---call the delegated method---
method("Using anonymous method.");
Console.ReadLine();
}
}
In this expression, the method
delegate is an anonymous method:
MethodsDelegate method = delegate(string Message) {
Console.WriteLine(Message);
};
Anonymous methods eliminate the need to define a separate method when using delegates. This is useful if your delegated method contains a few simple statements and is not used by other code because you reduce the coding overhead in instantiating delegates by not having to create a separate method.
In C# 3.0, anonymous methods can be further shortened using a new feature known as lambda expressions. Lambda expressions are a new feature in .NET 3.5 that provides a more concise, functional syntax for writing anonymous methods.
The preceding code using anonymous methods can be rewritten using a lambda expression:
class Program {
delegate void MethodsDelegate(string Message);
static void Main(string[] args) {
MethodsDelegate method = (Message) => { Console.WriteLine(Message); };
//---call the delegated method---
method("Using Lambda Expression.");
Console.ReadLine();
}
}
Lambda expressions are discussed in more detail in Chapter 14.
One of the most important techniques in computer science that made today's graphical user interface operating systems (such as Windows, Mac OS X, Linux, and so on) possible is event-driven programming. Event-driven programming lets the OS react appropriately to the different clicks made by the user. A typical Windows application has various widgets such as buttons, radio buttons, and checkboxes that can raise events when, say, a user clicks them. The programmer simply needs to write the code to handle that particular event. The nice thing about events is that you do not need to know when these events will be raised — you simply need to provide the implementation for the event handlers that will handle the events and the OS will take care of invoking the necessary event handlers appropriately.
In .NET, events are implemented using delegates. An object that has events is known as a publisher. Objects that subscribe to events (in other words, handle events) are known as subscribers. When an object exposes events, it defines a delegate so that whichever object wants to handle this event will have to provide a function for this delegate. This delegate is known as an event, and the function that handles this delegate is known as an event handler. Events are part and parcel of every Windows application. For example, using Visual Studio 2008 you can create a Windows application containing a Button
control (see Figure 7-4).
Figure 7-4
When you double-click the Button control, an event handler is automatically added for you:
public partial class Form1 : Form {
public Form1() {
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e) {
}
}
But how does your application know which event handler is for which event? Turns out that Visual Studio 2008 automatically wires up the event handlers in the code-behind of the form ( FormName.Designer.cs
; see Figure 7-5) located in a function called InitializeComponent()
:
this.button1.Location = new System.Drawing.Point(12, 12);
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(75, 23);
this.button1.TabIndex = 0;
this.button1.Text = "button1";
this.button1.UseVisualStyleBackColor = true;
this.button1.Click += new System.EventHandler(this.button1_Click);
Figure 7-5
Notice that the way you wire up an event handler to handle the Click
event is similar to how you assign a method name to a delegate.
Alternatively, you can manually create the event handler for the Click
event of the Button
control. In the Form()
constructor, type +=
after the Click
event and press the Tab key. Visual Studio 2008 automatically completes the statement (see Figure 7-6).
Читать дальше