一、关于委托的回顾
委托其实相当于C++里面的函数指针。官方描述是:委托是方法的类型安全的引用。
1、普通委托
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication1
{
//delegate定义的是一个类型,这个类型变量的值是签名相同的函数
delegate char getCharFromString(string str, int index);
class Program
{
static void Main(string[] args)
{
//定义一个getCharFromString(delegate)型的变量,并为其赋值。赋值的条件是:签名相同
getCharFromString fac = get;
//通过委托调用函数功能
Console.WriteLine(fac("yuyong", 2));
getCharFromString facNext = getNext;
Console.WriteLine(facNext("yuyong", 2));
Console.ReadKey();
}
static char get(string str, int index)
{
return str.ToArray()[index];
}
static char getNext(string str, int index)
{
return str.ToArray()[index + 1];
}
}
}
2、Func委托
Func委托是一种泛型委托,例如,上面的delegate char getCharFromString(string str, int index);等价于Func<string,int, char>
定义Func的类型列表最后一个类型是返回值类型,前面的类型都是输入参数类型。如果类型列表只有一个类型,那这个类型就是返回类型。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication1
{
delegate char getCharFromString(string str, int index);
class Program
{
static void Main(string[] args)
{
getCharFromString fac = get;
Console.WriteLine(fac("yuyong", 2));
getCharFromString facNext = getNext;
Console.WriteLine(facNext("yuyong", 2));
//定义与getCharFromString等价的Func<T>委托
Func<string, int, char> fac_func = get;
Console.WriteLine(fac_func("yuyong", 2));
Func<string, int, char> facNext_func = getNext;
Console.WriteLine(facNext_func("yuyong", 2));
Console.ReadKey();
}
static char get(string str, int index)
{
return str.ToArray()[index];
}
static char getNext(string str, int index)
{
return str.ToArray()[index + 1];
}
}
}
3、匿名委托
借助delegate关键字还可以定义匿名委托
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication1
{
delegate char getCharFromString(string str, int index);
class Program
{
static void Main(string[] args)
{
getCharFromString fac = delegate(string str, int index)
{
return str.ToArray()[index];
};
Console.WriteLine(fac("yuyong", 2));
Func<string, int, char> facNext = delegate(string str, int index)
{
return str.ToArray()[index + 1];
};
Console.WriteLine(facNext("yuyong", 2));
Console.ReadKey();
}
}
}
4、Lambda表达式
Lambda表达式实际上就是匿名委托的简写方式
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication1
{
delegate char getCharFromString(string str, int index);
class Program
{
static void Main(string[] args)
{
getCharFromString fac = delegate(string str, int index)
{
return str.ToArray()[index];
};
Console.WriteLine(fac("yuyong", 2));
Func<string, int, char> facNext = delegate(string str, int index)
{
return str.ToArray()[index + 1];
};
Console.WriteLine(facNext("yuyong", 2));
//Lambda表达式--------------------------------------------------
getCharFromString fac_la = (str, index) =>
{
return str.ToArray()[index];
};
Console.WriteLine(fac_la("yuyong", 2));
Func<string, int, char> facNext_la = (str, index) =>
{
return str.ToArray()[index + 1];
};
Console.WriteLine(facNext_la("yuyong", 2));
Console.ReadKey();
}
}
}
二、异步委托
委托变量可以异步地执行方法体。在后台,委托异步执行时会创建一个执行任务的线程。委托使用线程池来完成异步任务。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
myAsycTask task_a = myAsycFunc;
myResult result_a = new myResult();
//BeginInvoke方法会从线程池中取出线程资源并异步执行myAsycFunc方法
//BeginInvoke方法的形参列表是myAsycFunc方法的形参列表加上一个AsyncCallback类型参数,一个object类型参数
//AsyncCallback也是一个委托类型,BeginInvoke方法执行完成之后将回调这个委托方法
//AsyncCallback的签名是:输入IAsyncResult,输出void。object类型参数将作为这个IAsyncResult类型的值输入AsyncCallback方法
task_a.BeginInvoke("yuyong", 2, result_a, printResult, result_a);
Console.WriteLine("invoke back");
//启动线程的线程成为主线程,被启动的线程叫做主线程的子线程。当这个子线程是后台线程时,主线程在子线程完成之前就结束的话,子线程会强制结束。
Console.ReadKey();
}
//ar就是BeginInvoke的最后一个参数
static void printResult(IAsyncResult ar)
{
Console.WriteLine("task finish");
myResult result = (myResult)ar.AsyncState;
Console.WriteLine(result.char_index);
Console.WriteLine(result.char_index_next);
}
static void myAsycFunc(string str, int index, myResult result)
{
Console.WriteLine("begin myAsycFunc");
Thread.Sleep(5000);
result.char_index = str.ToArray()[index];
result.char_index_next = str.ToArray()[index + 1];
}
}
delegate void myAsycTask(string str, int index, myResult result);
class myResult
{
public char char_index { get; set; }
public char char_index_next { get; set; }
}
}