走进异步编程的世界在WinForm中执行异步操作概要Word下载.docx
- 文档编号:13648610
- 上传时间:2022-10-12
- 格式:DOCX
- 页数:14
- 大小:454.39KB
走进异步编程的世界在WinForm中执行异步操作概要Word下载.docx
《走进异步编程的世界在WinForm中执行异步操作概要Word下载.docx》由会员分享,可在线阅读,更多相关《走进异步编程的世界在WinForm中执行异步操作概要Word下载.docx(14页珍藏版)》请在冰豆网上搜索。
6}
7
8privatevoidbtnDo_Click(objectsender,EventArgse)
9{
10btnDo.Enabled=false;
11lblText.Text=@"
Doing"
;
12
13Thread.Sleep(3000);
14
15btnDo.Enabled=true;
16lblText.Text=@"
Complete"
17}
18}
可是执行结果却是:
图1-1
【发现的问题】
①好像没有变成“Doing”?
②并且拖动窗口的时候卡住不动了?
③3秒后突然变到想拖动到的位置?
④同时文本变成“Complete”?
【分析】GUI程序在设计中要求所有的显示变化都必须在主GUI线程中完成,如点击事件和移动窗体。
Windows
程序时通过消息来实现,消息放入消息泵管理的消息队列中。
点击按钮时,按钮的Click消息放入消息队列。
消息泵从队列中移除该消息,并开始处理点击事件的代码,即
btnDo_Click事件的代码。
btnDo_Click事件会将触发行为的消息放入队列,但在
btnDo_Click时间处理程序完全退出前(线程挂起3秒退出前),消息都无法执行。
(3秒后)接着所有行为都发生了,但速度太快肉眼无法分辨才没有发现标签改成“Doing”。
图1-2点击事件
图1-3点击事件具体执行过程
现在我们加入async/await特性。
8privateasyncvoidbtnDo_Click(objectsender,EventArgse)
13awaitTask.Delay(3000);
图1-4
现在,就是原先希望看到的效果。
【分析】btnDo_Click事件处理程序先将前两条消息压入队列,然后将自己从处理器移出,在3秒后(等待空闲任务完成后Task.Delay)再将自己压入队列。
这样可以保持响应,并保证所有的消息可以在线程挂起的时间内被处理。
1.1Task.Yield
Task.Yield方法创建一个立刻返回的awaitable。
等待一个Yield可以让异步方法在执行后续部分的同时返回到调用方法。
可以将其理解为离开当前消息队列,回到队列末尾,让CPU有时间处理其它任务。
1classProgram
3staticvoidMain(string[]args)
5constintnum=1000000;
6vart=DoStuff.Yield1000(num);
8Loop(num/10);
9Loop(num/10);
10Loop(num/10);
11
12Console.WriteLine($"
Sum:
{t.Result}"
);
13
14Console.Read();
15}
16
17///<
summary>
18///循环
19///<
/summary>
20///<
paramname="
num"
>
<
/param>
21privatestaticvoidLoop(intnum)
22{
23for(vari=0;
i<
num;
i++);
24}
25}
26
27internalstaticclassDoStuff
28{
29publicstaticasyncTask<
int>
Yield1000(intn)
30{
31varsum=0;
32for(inti=0;
n;
i++)
33{
34sum+=i;
35if(i%1000==0)
36{
37awaitTask.Yield();
//创建异步产生当前上下文的等待任务
38}
39}
40
41returnsum;
42}
43}
图1.1-1
上述代码每执行1000次循环就调用Task.Yield方法创建一个等待任务,让处理器有时间处理其它任务。
该方法在GUI程序中是比较有用的。
二、在WinForm中使用异步Lambda表达式
将刚才的窗口程序的点击事件稍微改动一下。
6
7//async(sender,e)异步表达式
8btnDo.Click+=async(sender,e)=>
10Do(false,"
12awaitTask.Delay(3000);
14Do(true,"
Finished"
15};
16}
17
18privatevoidDo(boolisEnable,stringtext)
19{
20btnDo.Enabled=isEnable;
21lblText.Text=text;
22}
23}
还是原来的配方,还是熟悉的味道,还是原来哪个窗口,变的只是内涵。
图2-1
三、一个完整的WinForm程序
现在在原来的基础上添加了进度条,以及取消按钮。
3privateCancellationTokenSource_source;
4privateCancellationToken_token;
5
6publicForm1()
7{
8InitializeComponent();
9}
10
11///<
12///Do按钮事件
13///<
14///<
sender"
15///<
e"
16privateasyncvoidbtnDo_Click(objectsender,EventArgse)
17{
18btnDo.Enabled=false;
19
20_source=newCancellationTokenSource();
21_token=_source.Token;
22
23varcompletedPercent=0;
//完成百分比
24constinttime=10;
//循环次数
25constinttimePercent=100/time;
//进度条每次增加的进度值
27for(vari=0;
time;
29if(_token.IsCancellationRequested)
31break;
32}
33
34try
35{
36awaitTask.Delay(500,_token);
37completedPercent=(i+1)*timePercent;
39catch(Exception)
40{
41completedPercent=i*timePercent;
43finally
44{
45progressBar.Value=completedPercent;
46}
47}
48
49varmsg=_token.IsCancellationRequested?
$"
进度为:
{completedPercent}%已被取消!
"
:
已经完成"
50
51MessageBox.Show(msg,@"
信息"
52
53progressBar.Value=0;
54InitTool();
55}
56
57///<
58///初始化窗体的工具控件
59///<
60privatevoidInitTool()
61{
62progressBar.Value=0;
63btnDo.Enabled=true;
64btnCancel.Enabled=true;
65}
66
67///<
68///取消事件
69///<
70///<
71///<
72privatevoidbtnCancel_Click(objectsender,EventArgse)
73{
74if(btnDo.Enabled)return;
75
76btnCancel.Enabled=false;
77_source.Cancel();
78}
79}
图3-1
四、另一种异步方式-BackgroundWorker类
与async/await不同的是,你有时候可能需要一个额外的线程,在后台持续完成某项任务,并不时与主线程通信,这时就需要用到
BackgroundW
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 走进 异步 编程 世界 WinForm 执行 操作 概要
![提示](https://static.bdocx.com/images/bang_tan.gif)