委托和事件是两个重要的方法,委托是包含方法引用的引用类型,相当于函数指针,但是它是类型安全类型,必须函数签名匹配委托签名。不是直接调用函数,而是使用委托指向该函数,通过调用委托来调用该函数。最重要实现一个叫回调的技术,该技术表示在某个函数结束执行时,对特定函数执行调用用以通知其执行已经完成。
定义:delegate 返回类型 委托名(签名,,);注意:没有函数体
委托的优点就是可以使用委托调用它指向的任何函数,并且在实际运行之前都不需要确切的了解它调用的函数。
可以讲委托作为形参传递给方法
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace delegateproj
{
class Program
{
//声明委托
delegate int mathdelegate(int num1, int num2);
static void per(mathdelegate method ,int num1,int num2 )//委托作为形参传递给方法
{
Console.WriteLine(method(num1, num2).ToString());
}
static void Main(string[] args)
{
int num1 = 3;
int num2 = 5;
mathdelegate method = new mathdelegate(add);
// mathdelegate method = add;
Console.WriteLine(method(num1, num2).ToString());
per(method, num1, num2);
}
static int add(int num1, int num2)//需要是静态的字段、方法或属性要求对象引用,否出错
{
return (num1 + num2);
}
static int subtract(int num1, int num2)
{
return (num1 - num2);
}
}
}
也可以使委托指向多个函数(多播委托)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace delegateproj
{
class Program
{
//声明委托
delegate void mathdelegate();
static void Main(string[] args)
{
mathdelegate method = method1;
method += method2;
method += method3;
method();
Console.ReadLine();
}
static private void method1()
{
Console.WriteLine("method1");
}
static private void method2()
{
Console.WriteLine("method2");
}
static private void method3()
{
Console.WriteLine("method3");
}
}
}
实现回调技术
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace delegateproj
{
class Program
{
//声明委托
delegate void callbackdelegate(string Message);
static void Main(string[] args)
{
callbackdelegate result = resultcallback; //resultcallback不加()明明有参数???
add(3, 5, result);//计算完成时调用callback委托并向其传递一个字符串,
//callback委托调用resultcallback( ) 函数输出到控制台
Console.ReadLine();
}
static private void add(int num1,int num2 ,callbackdelegate callback)
{
int result =num1+num2;
callback("the result is " + result.ToString());
}
static private void resultcallback(string Message)
{
Console.WriteLine(Message);
}
}
}
异步委托
提供以异步方式调用同步方法的能力。当同步调用一个委托时,“Invoke”方法直接对当前线程调用目标方法。如果编译器支持异步委托,则它将生成“Invoke”方法以及“BeginInvoke”和“EndInvoke”方法。如果调用“BeginInvoke”方法,则公共语言运行库 (CLR) 将对请求进行排队并立即返回到调用方。将对来自线程池的线程调用该目标方法。提交请求的原始线程自由地继续与目标方法并行执行,该目标方法是对线程池线程运行的。如果在对“BeginInvoke”方法的调用中指定了回调方法,则当目标方法返回时将调用该回调方法。在回调方法中,“EndInvoke”方法获取返回值和所有输入/输出参数。如果在调用“BeginInvoke”时未指定任何回调方法,则可以从调用“BeginInvoke”的线程中调用“EndInvoke”。
重要说明: |
---|
使用用户指定的委托签名,编译器应发出具有“Invoke”、“BeginInvoke”和“EndInvoke”方法的委托类。“BeginInvoke”和“EndInvoke”方法应被修饰为本机的。因为这些方法被标记为本机的,所以 CLR 在类加载时自动提供该实现。加载程序确保它们未被重写。 |
using System; using System.Threading; namespace Examples.AdvancedProgramming.AsynchronousOperations { public class AsyncMain { // Asynchronous method puts the thread id here. private static int threadId; static void Main() { // Create an instance of the test class. AsyncDemo ad = new AsyncDemo(); // Create the delegate. AsyncMethodCaller caller = new AsyncMethodCaller(ad.TestMethod); // Initiate the asychronous call. Include an AsyncCallback // delegate representing the callback method, and the data // needed to call EndInvoke. IAsyncResult result = caller.BeginInvoke(3000, out threadId, new AsyncCallback(CallbackMethod), caller ); Console.WriteLine("Press Enter to close application."); Console.ReadLine(); } // Callback method must have the same signature as the // AsyncCallback delegate. static void CallbackMethod(IAsyncResult ar) { // Retrieve the delegate. AsyncMethodCaller caller = (AsyncMethodCaller) ar.AsyncState; // Call EndInvoke to retrieve the results. string returnValue = caller.EndInvoke(out threadId, ar); Console.WriteLine("The call executed on thread {0}, with return value \"{1}\".", threadId, returnValue); } } }