-
1.委托
-
-
-
-
1.1 声明委托:
-
在C#中,委托类似于“类”,定义的前面要加上关键字delegate,可以在类的内部定义,也可以在外部定义,还可以在空间中把委托定义为顶层对象。根据可见性,和委托的作用域,可以在委托的定义上应用任何常见的访问修饰符:public,private,protected等。
-
public delegate string GetString(); class Program { delegate double TowLongsOp(long first, long second); }
-
-
1.2 使用委托:
-
1.2.1 为什么使用委托:
-
需要将方法作为参数传递给一个方法,而且我们不知道需要传递的方法是什么。
-
-
-
1.2.2 如何使用委托:
-
委托的实例可以引用任何类型的任何对象上的实例方法或静态方法——只要方法的签名匹配于委托的签名即可。
-
//该委托表示的方法有两个long型参数,返回类型为double delegate double TowLongsOp(long first, long second); //该委托表示的方法有一个int型参数,返回类型为void delegate void IntMethodInvoker(int x);
public delegate string GetString(int x); public class MyClass { public string TT(int x) { return "liang:" + x.ToString(); } public static string TTT(int x) { return "liang static:" + x.ToString(); } } class Program { static void Main(string[] args) { GetString getString1 = new GetString(MyClass.TTT); Console.WriteLine(getString1(1)); MyClass my = new MyClass(); GetString getString2 = new GetString(my.TT); Console.WriteLine(getString2(2)); } }
-
1.3 Action<T>和Func<T>委托
-
Action<T>表示引用一个void返回类型的方法。该委托类存在不同的变体,可以传递至多16种不同的参数类型。
-
Func<T>允许带有返回类型的方法。Func<out TResult>委托类型可以调用带返回类型且无参数的方法。Func<in T, out TResult>调用带一个参数的方法。
-
class BubbleSorter { static public void Sort<T>(IList<T> sortArray, Func<T, T, bool> comparison) { bool swapped = true; do { swapped = false; for (int i = 0; i < sortArray.Count - 1; i++) { if (comparison(sortArray[i + 1], sortArray[i])) { T temp = sortArray[i]; sortArray[i] = sortArray[i + 1]; sortArray[i + 1] = temp; swapped = true; } } } while (swapped); } } class Employee { public string Name { get; private set; } public decimal Salary { get; private set; } public Employee(string name, decimal salary) { this.Name = name; this.Salary = salary; } public override string ToString() { return string.Format("{0},{1:C}", Name, Salary); } public static bool CompareSalary(Employee e1, Employee e2) { return e1.Salary < e2.Salary; } } class Program { static void Main(string[] args) { Employee[] employees = { new Employee("T1",20000), new Employee("T2",10000), new Employee("T3",30000), new Employee("T4",23000), new Employee("T5",10000.38m) }; BubbleSorter.Sort(employees, Employee.CompareSalary); foreach (var employee in employees) { Console.WriteLine(employee); } }
-
1.4 多播委托
-
包含多个方法的委托,叫做多播委托。调用多播委托,就可以按照顺序连续调用多个方法。为此,委托的签名就必须返回void。也可以使用返回类型为void的Action<double>委托。
-
class MathOperations { public static void multiplyByTwo(double value) { double result = value * 2; Console.WriteLine(result); } public static void Square(double value) { double result = value * value; Console.WriteLine(result); } } class Program { static void Main(string[] args) { Action<double> operations = MathOperations.multiplyByTwo; operations += MathOperations.Square; operations(3); } }
- 使用多播委托,由于多播委托包含一个逐个调用的委托集合。如果童工委托调用其中一个方法抛出异常,整个迭代就会停止。
-
1.5 代理异步使用(Invoke和BeginInvoke)
-
1.5.1.直接使用EndInvoke方法来获得返回值
-
当使用BeginInvoke异步调用方法时,如果方法未执行完,EndInvoke方法就会一直阻塞,直到被调用方法执行完毕。
-
class Program { private static int newTask(int ms) { Console.WriteLine("任务开始"); Thread.Sleep(ms); Random random = new Random(); int n = random.Next(10000); Console.WriteLine("任务完成"); return n; } private delegate int NewTaskDelegate(int ms); static void Main(string[] args) { Thread.Sleep(1000); NewTaskDelegate nd = newTask; IAsyncResult asyncResult = nd.BeginInvoke(2000, null, null); int result = nd.EndInvoke(asyncResult); Console.WriteLine(result); } }
-
1.5.2.使用IAsyncResult属性来判断异步调用是否完成
-
虽然上面的方法可以很好的实现异步调用,但是当调用EndInvoke方法获得结果时,整个程序就像死了一样,这样做用户的感觉不会很好,可是使用IAsyncResult属性来判断异步操作是否完成,并提示一些信息。
-
class Program { private static int newTask(int ms) { Console.WriteLine("任务开始"); Thread.Sleep(ms); Random random = new Random(); int n = random.Next(10000); Console.WriteLine("任务完成"); return n; } private delegate int NewTaskDelegate(int ms); static void Main(string[] args) { Thread.Sleep(1000); NewTaskDelegate nd = newTask; IAsyncResult asyncResult = nd.BeginInvoke(2000, null, null); while (!asyncResult.IsCompleted) { Console.Write("*"); Thread.Sleep(100); } int result = nd.EndInvoke(asyncResult); Console.WriteLine(result); }
-
1.5.3.使用WaitOne方法等待异步方法执行完成
-
使用WaitOne方法是另外一种判断异步调用的方法。
-
WaitOne第一个参数表示要等待的毫秒数,在指定的时间内,WaitOne将一直等待,直到异步调用完成, 并发出通知,WaitOne方法才返回true。当等待指定时间之后,异步调用仍未完成,WaitOne方法返回false,如果指定时间为0,表示不等待,如果为-1,表示永远等待,直到异步调用完成。
-
private static int newTask(int ms) { Console.WriteLine("任务开始"); Thread.Sleep(ms); Random random = new Random(); int n = random.Next(10000); Console.WriteLine("任务完成"); return n; } private delegate int NewTaskDelegate(int ms); static void Main(string[] args) { Thread.Sleep(1000); NewTaskDelegate nd = newTask; IAsyncResult asyncResult = nd.BeginInvoke(2000, null, null); while (!asyncResult.AsyncWaitHandle.WaitOne(100, false)) { Console.Write("*"); } int result = nd.EndInvoke(asyncResult); Console.WriteLine(result); }
-
-
1.5.4.使用回调方式返回结果
-
上面介绍的几种方法实际上只相当于一种方法。这些方法虽然可以成功返回结果,也可以给用户一些提示,但是在这个过程中,整个程序就像死了一样。在GUI中比较明显。要想在调用的过程中,程序仍然可以正常做其它的工作,就必须使用异步调用的方式。
-
-
-
-
转载于:https://www.cnblogs.com/liangdiamond/archive/2013/01/09/2853654.html