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 }