异步是现实生活中的不少现象的一种抽象。好比分工合做在不少时间段就是异步合做。异步中也通常要涉及委托方法。c#有3种模式的异步编程:异步模式,基于事件的异步模式,基于任务的异步模式(TAP).html
一. FrameWork 4.0以前的线程世界 编程
在.NET FrameWork 4.0以前,若是咱们使用线程。通常有如下几种方式:c#
二. .Net 传统异步编程概述 异步
三. Task 的优势以及功能 async
第一种 异步模式 异步编程
public class 异步调用 { static void Main() { Console.WriteLine("===== 异步调用 AsyncInvokeTest ====="); AddHandler handler = new AddHandler(加法类.Add); //IAsyncResult: 异步操做接口(interface) //BeginInvoke: 委托(delegate)的一个异步方法的开始 IAsyncResult result = handler.BeginInvoke(1, 2, null, null); Console.WriteLine("继续作别的事情。。。"); //异步操做返回 EndInvoke方式会阻塞主线程 须要等待异步线程调用完毕 才会执行 Console.WriteLine(handler.EndInvoke(result)); Console.ReadKey(); } }
public class 异步回调 { static void Main() { Console.WriteLine("===== 异步回调 AsyncInvokeTest ====="); AddHandler handler = new AddHandler(加法类.Add); //异步操做接口(注意BeginInvoke方法的不一样!) IAsyncResult result = handler.BeginInvoke(1,2,new AsyncCallback(回调函数),"AsycState:OK"); Console.WriteLine("继续作别的事情。。。"); Console.ReadKey(); } static void 回调函数(IAsyncResult result) { //result 是“加法类.Add()方法”的返回值 //AsyncResult 是IAsyncResult接口的一个实现类,空间:System.Runtime.Remoting.Messaging //AsyncDelegate 属性能够强制转换为用户定义的委托的实际类。 AddHandler handler = (AddHandler)((AsyncResult)result).AsyncDelegate; //或者 AddHandler handler=result.AsyncState as AddHandler; Console.WriteLine(handler.EndInvoke(result)); Console.WriteLine(result.AsyncState); } }
利用lambda表达式简单写法 (这个很经常使用。必定要理解和学会。)函数
// public delegate string TakesAWhileDelegate(int data1, int data2); 定义一个委托 TakesAWhileDelegate dl = (a, b) => { return (a + b).ToString(); }; //委托 实例化 dl.BeginInvoke(1, 12, result => { //回调方法 实例化 string str=dl.EndInvoke(result); //EndInvoke方法取回结果 Console.WriteLine("取到异步的结果了result={0}", str); }, null);
第二种 基于事件的异步模式网站
.net中不少类的方法都定义了同步和异步两种模式,例如WebClient类,就定义了DownloadStringAsync基于事件的异步模式。.net
WebClient wc = new WebClient(); string strUI = "我是主线程中的元素"; wc.Encoding = Encoding.UTF8; //首先实例化 Completed事件。 注意:能够直接访问UI线程中的元素 // public delegate void DownloadStringCompletedEventHandler(object sender, DownloadStringCompletedEventArgs e); wc.DownloadStringCompleted += (sender1, e1) => { //e1 存放结果 Console.WriteLine(strUI); string str = e1.Result; Console.WriteLine(str); }; wc.DownloadStringAsync(new Uri("http://www.baidu.com")); Console.WriteLine("继续主线程,不会由于访问网站而阻塞");
第三种 基于任务的异步模式(Task,await,async关键字)线程
private void button21_Click(object sender, EventArgs e) { Console.WriteLine("主线程已经开始了"); CallerWithAsync(); //调用基于任务的异步方法 Console.WriteLine("主线程已经结束了"); } //建立基于任务的异步方法 private async void CallerWithAsync() { //async(方法修饰符)和await必须成对出现。顺序执行 string result = await GetAsync("第1个"); //等待 方法执行结果 阻塞线程。编译器把await关键字后的全部代码放进ContinueWith方法的代码块中 string result2 = await GetAsync("第2个"); Console.WriteLine("任务第3"); } //经过任务使同步方法异步化 private Task<string> GetAsync(string name) { return Task.Run<string>(() => { Thread.Sleep(2000); Console.WriteLine(name); return name; }); }
TASK的用法 请参考这篇文章