1 using System; 2 using System.Collections.Generic; 3 using System.ComponentModel; 4 using System.Data; 5 using System.Diagnostics; 6 using System.Drawing; 7 using System.Linq; 8 using System.Text; 9 using System.Threading; 10 using System.Windows.Forms; 11 12 namespace 异步Async 13 { 14 /* 15 * 1.同步启动时会卡主界面,异步不会,原因是异步调用了子线程去执行,使主线程得到释放 16 * 2.同步方法慢,异步方法快,启动多线程,占用更多资源 17 * 3.异步是无序的 18 */ 19 public partial class Form1 : Form 20 { 21 public Form1() 22 { 23 InitializeComponent(); 24 } 25 26 27 private Action<string> act; //定义一个无返回结果委托 28 private Func<string, long> func; //定义一个有返回结果委托 29 30 /// <summary> 31 /// 异步调用 32 /// </summary> 33 /// <param name="sender"></param> 34 /// <param name="e"></param> 35 private void btnAsync_Click(object sender, EventArgs e) 36 { 37 //act = t => Console.WriteLine("别跟我BB,{0},当前线程是{1}",t,Thread.CurrentThread.ManagedThreadId); 38 //act.BeginInvoke("你大爷还是你大爷",null,null); 39 40 //将DoSomething方法执行5次 41 Console.WriteLine("*****************异步方法btnAsync_Click****************"); 42 43 for (int i = 0; i < 5; i++) 44 { 45 act = DoSomething; //需要结合委托使用 46 act.BeginInvoke("异步", null, null); //异步启动多个线程调用DoSomething()方法 47 //第一个参数为DoSomething()方法的name参数,第二为回调函数,第三为回调函数的状态参数 48 } 49 Console.WriteLine("*****************异步方法btnAsync_Click****************"); 50 Console.WriteLine(" "); 51 } 52 53 /// <summary> 54 /// 异步进阶 55 /// </summary> 56 /// <param name="sender"></param> 57 /// <param name="e"></param> 58 private void btnAsyncAdvanced_Click(object sender, EventArgs e) 59 { 60 Console.WriteLine("*****************异步进阶btnAsync_Click****************"); 61 act = DoSomething; 62 63 AsyncCallback back = t => Console.WriteLine("这里是回调函数,当前线程ID是{0},AsyncState为{1}",Thread.CurrentThread.ManagedThreadId,t.AsyncState); 64 65 IAsyncResult result= act.BeginInvoke("异步回调", back, "回调参数param思密达"); //异步回调,添加回调参数 66 67 /* 68 //异步等待1 69 result.AsyncWaitHandle.WaitOne(-1); //主线程无限期等待子线程结束,相当于回到同步 70 71 //异步等待2,可以做进度条 72 while (!result.IsCompleted) 73 { 74 Thread.Sleep(100); 75 Console.WriteLine("请继续等待......."); 76 } 77 78 //异步等待3 79 act.EndInvoke(result); 80 */ 81 82 Console.WriteLine("*****************异步进阶btnAsync_Click****************"); 83 Console.WriteLine(" "); 84 } 85 86 /// <summary> 87 /// 异步进阶2,调用有返回结果的方法 88 /// </summary> 89 /// <param name="sender"></param> 90 /// <param name="e"></param> 91 private void btnAsyncAdv2_Click(object sender, EventArgs e) 92 { 93 Console.WriteLine("*****************异步进阶2btnAsync_Click****************"); 94 func = GetDoSomething; 95 96 /*第一种异步等待等到该GetDoSomething()方法的返回结果,但是会卡住主线程 97 98 IAsyncResult result = func.BeginInvoke("异步进阶2", t =>Console.WriteLine("这里是回调函数,当前线程ID是{0},AsyncState为{1}", Thread.CurrentThread.ManagedThreadId, t.AsyncState), "哈哈哈param"); 99 100 101 在等待的过程中可以做别的很多事........ 102 这里可以调用其它方法 103 104 105 long r = func.EndInvoke(result); 106 Console.WriteLine("sum的结果为:{0}",r); 107 108 */ 109 110 //第二种异步等待结果,直接将等待方法EndInvoke()写入回调函数中,注:拉姆达表达式的匿名函数可以写成 new AsyncCallback(回调函数名),该函数需加参数(IAsyncResult result) 111 112 //注:t为得到的result,第二种的好处是不会卡住主线程,因为异步等待在子线程中运行 113 IAsyncResult result = func.BeginInvoke("异步进阶2", t => 114 { 115 Console.WriteLine("这里是回调函数,当前线程ID是{0},AsyncState为{1}", Thread.CurrentThread.ManagedThreadId, t.AsyncState); 116 117 //在这里直接得到GetDoSomething()方法的返回结果,6不6 118 long r = func.EndInvoke(t); 119 Console.WriteLine("sum的结果为:{0}",r); 120 }, "哈哈哈param"); 121 122 123 //下面在等待过程中可以做别的很多事....... 124 //可以调用其它方法,如: 125 Console.WriteLine("这里可以做别的事儿......"); 126 127 128 Console.WriteLine("*****************异步进阶2btnAsync_Click****************"); 129 } 130 131 /// <summary> 132 /// 同步调用 133 /// </summary> 134 /// <param name="sender"></param> 135 /// <param name="e"></param> 136 private void btnSync_Click(object sender, EventArgs e) 137 { 138 //将DoSomething执行5次 139 Console.WriteLine("*****************同步方法btnSync_Click****************"); 140 for (int i = 0; i < 5; i++) 141 { 142 DoSomething("同步"); 143 } 144 Console.WriteLine("*****************同步方法btnSync_Click****************"); 145 Console.WriteLine(" "); 146 } 147 148 /// <summary> 149 /// 耗时void无返回结果方法 150 /// </summary> 151 /// <param name="name"></param> 152 private void DoSomething(string name) 153 { 154 //监控此方法所用时间 155 Stopwatch watch = new Stopwatch(); 156 watch.Start(); 157 Console.WriteLine("当前是{0}在调用次方法,当前线程ID是{1}",name,Thread.CurrentThread.ManagedThreadId); 158 long sum = 0; 159 for (int i = 0; i < 1000000000; i++) 160 { 161 sum += i; 162 } 163 Thread.Sleep(1000); //等待1秒 164 watch.Stop(); 165 Console.WriteLine("sum结果是:{0},耗时{1}", sum, watch.ElapsedMilliseconds); 166 } 167 168 /// <summary> 169 /// 有返回结果的方法 170 /// </summary> 171 /// <param name="name"></param> 172 /// <returns></returns> 173 private long GetDoSomething(string name) 174 { 175 long sum = 0; 176 for (int i = 0; i < 1000000000; i++) 177 { 178 sum += i; 179 } 180 return sum; 181 } 182 } 183 }