琦琦的光阴管理六万分法则

倒上前异步编程的社会风气 – 在 GUI 中履行异步操作

   
真正的日管理,并无是受您以少日外匆匆忙忙地做到很多业务,而是吃您于对立轻松、悠闲的状态下自然而然地成功,做每一样项事都是气定神闲的状态。——行动派琦琦

【博主】反骨仔  【原文地址】http://www.cnblogs.com/liqingwen/p/5877042.html 

学科收听地址:时光管理上篇在线收听_mp3下载_喜马拉雅听

   这是继《[开始接触 async/await

                   
  岁月管理下篇在线收听_mp3下载_喜马拉雅听

异步编程](http://www.cnblogs.com/liqingwen/p/5831951.html)》、《[走进异步编程的世界

解析异步方法](http://www.cnblogs.com/liqingwen/p/5844095.html)》后的第三篇。主要介绍在
WinForm 中怎么样实施异步操作。

 

1、树立“一边一边”的干活观念

目录

  • 每当 WinForm
    中实践异步操作
  • 在 WinForm 中应用异步 Lambda
    表达式
  • 一个完全的 WinForm
    程序
  • 任何一样种植异步方式 – BackgroundWorker

 

   
没人能搞活万全都的准备再次起来工作,都是初步举行下慢慢迭代。你得一边害怕、一边犹豫、一边不知底,又一方面开业务。当你“一边一边”时,事情反而以进向上——因为若未曾盖好之各种心态还是其他因停滞不前。小步快飞、快速迭代,任何事情都有易得还好的恐怕。

一律、在 WinForm 程序中执异步操作

  下面通过窗体示例演示以下操作-点击按钮后:

    ①将按钮禁用,并以标签内容改动化:“Doing”(表示执行中);

    ②线程挂于3秒(模拟耗时操作);

    ③启用按钮,将标签内容变更吧:“Complete”(表示执行到位)。

 1     public partial class Form1 : Form
 2     {
 3         public Form1()
 4         {
 5             InitializeComponent();
 6         }
 7 
 8         private void btnDo_Click(object sender, EventArgs e)
 9         {
10             btnDo.Enabled = false;
11             lblText.Text = @"Doing";
12 
13             Thread.Sleep(3000);
14 
15             btnDo.Enabled = true;
16             lblText.Text = @"Complete";
17         }
18     }

  可是执行结果却是:

葡京在线开户 1

图1-1

 

  【发现的题材】

    ①看似从来不成为“Doing”?

    ②并且拖动窗口的时卡住不动了?

    ③3秒后突然变换到想拖动到之职务?

    ④而文本变成“Complete”?

 

  【分析】GUI
程序于计划被求具有的示变化还必于主 GUI
线程中做到,如点击事件以及倒窗体。Windows 程序时通过
消息来落实,消息放入消息泵管理之音讯队列中。点击按钮时,按钮的Click消息放入消息队列。消息泵从队列中易除了该消息,并开始拍卖点击事件之代码,即 btnDo_Click
事件的代码。

  btnDo_Click 事件会将触发行为的消息放入队列,但当 btnDo_Click
时间处理程序完全剥离前(线程挂于 3 秒退出前),消息都心有余而力不足履行。(3
秒后)接着有行为还来了,但速度极抢肉眼无法分辨才没有察觉标签改化“Doing”。

葡京在线开户 2

希冀1-2 点击事件

葡京在线开户 3

贪图1-3 点击事件具体实践进程

  

  现在我们参加 async/await 特性。

 1     public partial class Form1 : Form
 2     {
 3         public Form1()
 4         {
 5             InitializeComponent();
 6         }
 7 
 8         private async void btnDo_Click(object sender, EventArgs e)
 9         {
10             btnDo.Enabled = false;
11             lblText.Text = @"Doing";
12 
13             await Task.Delay(3000);
14 
15             btnDo.Enabled = true;
16             lblText.Text = @"Complete";
17         }
18     }

葡京在线开户 4

图1-4

  现在,就是原希望见到的效用。

  【分析】btnDo_Click
事件处理程序先拿眼前少长条消息压入队列,然后将自己于电脑移出,在3秒后(等待空闲任务成功后
Task.Delay
)再以团结压入队列。这样好保障响应,并包拥有的消息可以在线程挂于底时光外于处理。

 

2、思维导图很重大

 1.1 Task.Yield

  Task.Yield 方法创建一个即时返的
awaitable。等待一个Yield可以为异步方法以执行后续有的以返回到调用方法。可以用那知也
离开时消息队列,回到阵末尾,让 CPU 有工夫处理外任务。

 1     class Program
 2     {
 3         static void Main(string[] args)
 4         {
 5             const int num = 1000000;
 6             var t = DoStuff.Yield1000(num);
 7 
 8             Loop(num / 10);
 9             Loop(num / 10);
10             Loop(num / 10);
11 
12             Console.WriteLine($"Sum: {t.Result}");
13 
14             Console.Read();
15         }
16 
17         /// <summary>
18         /// 循环
19         /// </summary>
20         /// <param name="num"></param>
21         private static void Loop(int num)
22         {
23             for (var i = 0; i < num; i++) ;
24         }
25     }
26 
27     internal static class DoStuff
28     {
29         public static async Task<int> Yield1000(int n)
30         {
31             var sum = 0;
32             for (int i = 0; i < n; i++)
33             {
34                 sum += i;
35                 if (i % 1000 == 0)
36                 {
37                     await Task.Yield(); //创建异步产生当前上下文的等待任务
38                 }
39             }
40 
41             return sum;
42         }
43     }

葡京在线开户 5

 图1.1-1

  上述代码每执行1000次等巡回就调用 Task.Yield
方法创建一个待任务,让电脑有工夫拍卖其他任务。该法以 GUI
程序中凡比较有效的。

 

   
很多人口做事时首先会见怀念“好难啊”“我未理解怎么开啊”,但一旦出一张白纸和同等开销笔,画来你的思维导图,答案恐怕跃然纸上,也就“站在迷宫之上看迷宫”。不用管问题交给他人,通过思想导图,细化步骤、连接不同的idea,自己便好分析出答案,自己虽是投机的强神。经常做思想导图,思维都见面转换清晰哦!一个浩浩荡荡的靶子,刚刚开始的均等步也许很小,分析出来,去开就是吓了。

老二、在 WinForm 中使用异步 Lambda 表达式

  将刚刚之窗口程序的点击事件稍微改变一下。

 1     public partial class Form1 : Form
 2     {
 3         public Form1()
 4         {
 5             InitializeComponent();
 6 
 7             //async (sender, e) 异步表达式
 8             btnDo.Click += async (sender, e) =>
 9             {
10                 Do(false, "Doing");
11 
12                 await Task.Delay(3000);
13 
14                 Do(true, "Finished");
15             };
16         }
17 
18         private void Do(bool isEnable, string text)
19         {
20             btnDo.Enabled = isEnable;
21             lblText.Text = text;
22         }
23     }

  还是原的配方,还是熟悉的寓意,还是本来哪个窗口,变的单独是内涵。

葡京在线开户 6

图2-1

 

   
另外,思维导图也可拉你发觉波解决的严重性点,例如李欣频先生人生之重中之重作业虽是有写,书出版了,大量的传媒、用户、资源、收益都来了,人生都为此开展。发现了重点点,时间的无用浪费点也会显露出水面。手账也推进分析思路,大家呢足以品尝下。

其三、一个总体的 WinForm 程序

  现在以原先的根基及加加了速度漫长,以及取消按钮。

 1     public partial class Form1 : Form
 2     {
 3         private CancellationTokenSource _source;
 4         private CancellationToken _token;
 5 
 6         public Form1()
 7         {
 8             InitializeComponent();
 9         }
10 
11         /// <summary>
12         /// Do 按钮事件
13         /// </summary>
14         /// <param name="sender"></param>
15         /// <param name="e"></param>
16         private async void btnDo_Click(object sender, EventArgs e)
17         {
18             btnDo.Enabled = false;
19 
20             _source = new CancellationTokenSource();
21             _token = _source.Token;
22 
23             var completedPercent = 0; //完成百分比
24             const int time = 10; //循环次数
25             const int timePercent = 100 / time; //进度条每次增加的进度值
26 
27             for (var i = 0; i < time; i++)
28             {
29                 if (_token.IsCancellationRequested)
30                 {
31                     break;
32                 }
33 
34                 try
35                 {
36                     await Task.Delay(500, _token);
37                     completedPercent = (i + 1) * timePercent;
38                 }
39                 catch (Exception)
40                 {
41                     completedPercent = i * timePercent;
42                 }
43                 finally
44                 {
45                     progressBar.Value = completedPercent;
46                 }
47             }
48 
49             var msg = _token.IsCancellationRequested ? $"进度为:{completedPercent}% 已被取消!" : $"已经完成";
50 
51             MessageBox.Show(msg, @"信息");
52 
53             progressBar.Value = 0;
54             InitTool();
55         }
56 
57         /// <summary>
58         /// 初始化窗体的工具控件
59         /// </summary>
60         private void InitTool()
61         {
62             progressBar.Value = 0;
63             btnDo.Enabled = true;
64             btnCancel.Enabled = true;
65         }
66 
67         /// <summary>
68         /// 取消事件
69         /// </summary>
70         /// <param name="sender"></param>
71         /// <param name="e"></param>
72         private void btnCancel_Click(object sender, EventArgs e)
73         {
74             if (btnDo.Enabled) return;
75 
76             btnCancel.Enabled = false;
77             _source.Cancel();
78         }
79     }

葡京在线开户 7

 图3-1

 

3、勇敢地为投机要助理,为帮手付费

季、另一样栽异步方式 – BackgroundWorker 类

  以及 async/await
不同的是,你发时分恐怕得一个格外的线程,在后台持续好某项任务,并不时同主线程通信,这时就得为此到 BackgroundWorker
类。主要用于 GUI 程序。

  书中的千言万语不及一个简便的以身作则。

 1     public partial class Form2 : Form
 2     {
 3         private readonly BackgroundWorker _worker = new BackgroundWorker();
 4 
 5         public Form2()
 6         {
 7             InitializeComponent();
 8 
 9             //设置 BackgroundWorker 属性
10             _worker.WorkerReportsProgress = true;   //能否报告进度更新
11             _worker.WorkerSupportsCancellation = true;  //是否支持异步取消
12 
13             //连接 BackgroundWorker 对象的处理程序
14             _worker.DoWork += _worker_DoWork;   //开始执行后台操作时触发,即调用 BackgroundWorker.RunWorkerAsync 时触发
15             _worker.ProgressChanged += _worker_ProgressChanged; //调用 BackgroundWorker.ReportProgress(System.Int32) 时触发
16             _worker.RunWorkerCompleted += _worker_RunWorkerCompleted;   //当后台操作已完成、被取消或引发异常时触发
17         }
18 
19         /// <summary>
20         /// 当后台操作已完成、被取消或引发异常时发生
21         /// </summary>
22         /// <param name="sender"></param>
23         /// <param name="e"></param>
24         private void _worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
25         {
26             MessageBox.Show(e.Cancelled ? $@"进程已被取消:{progressBar.Value}%" : $@"进程执行完成:{progressBar.Value}%");
27             progressBar.Value = 0;
28         }
29 
30         /// <summary>
31         /// 调用 BackgroundWorker.ReportProgress(System.Int32) 时发生
32         /// </summary>
33         /// <param name="sender"></param>
34         /// <param name="e"></param>
35         private void _worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
36         {
37             progressBar.Value = e.ProgressPercentage;   //异步任务的进度百分比
38         }
39 
40         /// <summary>
41         /// 开始执行后台操作触发,即调用 BackgroundWorker.RunWorkerAsync 时发生
42         /// </summary>
43         /// <param name="sender"></param>
44         /// <param name="e"></param>
45         private static void _worker_DoWork(object sender, DoWorkEventArgs e)
46         {
47             var worker = sender as BackgroundWorker;
48             if (worker == null)
49             {
50                 return;
51             }
52 
53             for (var i = 0; i < 10; i++)
54             {
55                 //判断程序是否已请求取消后台操作
56                 if (worker.CancellationPending)
57                 {
58                     e.Cancel = true;
59                     break;
60                 }
61 
62                 worker.ReportProgress((i + 1) * 10);    //触发 BackgroundWorker.ProgressChanged 事件
63                 Thread.Sleep(250);  //线程挂起 250 毫秒
64             }
65         }
66 
67         private void btnDo_Click(object sender, EventArgs e)
68         {
69             //判断 BackgroundWorker 是否正在执行异步操作
70             if (!_worker.IsBusy)
71             {
72                 _worker.RunWorkerAsync();   //开始执行后台操作
73             }
74         }
75 
76         private void btnCancel_Click(object sender, EventArgs e)
77         {
78             _worker.CancelAsync();  //请求取消挂起的后台操作
79         }
80     }

葡京在线开户 8

图4-1

 

   
平安保险皇后叶云燕,在友好或者多少主持(下属出三只人)时即也团结到底了帮手,目前它们底羽翼团队曾经发二三十单人口,非常管用地分担了成千上万零星或非擅的工作。琦琦也透过学习,在祥和刚做媒体、工资无赛时即通过豆瓣找了一如既往位网络助理,帮她开论坛、贴吧等创新工作,自己虽可留意于好的采集和移动策划上,也许这就是是琦琦火速成为副主编的门径有。请助理,是花钱买进时、为协调投资的好措施有。这是一个搭档之时日,请一各类助手,与出色之总人口一块坐班,是深高的习惯。

 传送门

  入门:《[走上前异步编程的社会风气

  • 初步接触 async/await
    异步编程](http://www.cnblogs.com/liqingwen/p/5831951.html)》

  上篇:《运动上前异步编程的世界 –
剖析异步方法(上)》《[走上前异步编程的世界

  • 浅析异步方法(下)](http://www.cnblogs.com/liqingwen/p/5866241.html)》

 

 


4、建立你的顾问团

【参考】《Illustrated C# 2012》

   
很多台湾丁从小便时有发生谈得来时去看的社区医院专属医师,每次身体无痛快去看病,医生还见面依据以前的病史、生活习惯、家族体质等地方对症下药,这是基本上好的等同项事呀,想想去特别医院,排队一小时看病五分钟。了解及这一点,琦琦就起注意身边是否来确切的大夫开专属医生,并转达给医生“专属医师”这个概念。医生听到这个,会以为你无是来来去去的买主,互相信任,便会尤其用心地治,并当新生把全家都看得不可开交好,也化为非常好之情侣。

   
延伸开始来,既然可以来专属医师,为什么不克当旁方为找到有专属顾问也,服装顾问、专属发型师、皮肤顾问、私人旅行智囊等等。请顾问并也顾问付费,你会获得更多之时光与还从容的生活。

5、建立你跟数的上扬小组

   
与行动派伙伴圈或读书会的定义类似,找到同频的伙伴,对每个人之发展都非常有助力。也许你说,你无精,是以身边无优秀的冤家,但并非如此。找到好变漂亮的朋友组队,大家好合由平庸走向优秀。这中间,分享是死重大的一些。有志同道合的伴侣联手,坚持会变换得特别爱。

   
(关于享受,我想开了《三体》作者刘慈欣的短篇小说《乡村教师》自己的葡京在线开户阅读微博分享,没有记忆遗传、用声波交流、没有外部力量部署,光赖人类自己还是能前进到被外星人难以置信的盛,教师是社会风气上无限伟大的分享者。透过教师,我们吧能来看分享的力量。)

6、快速学习,马上行

   
这同样碰于琦琦的另外一个旋律中发出特别好之笺注:听话照做随没错在线收听_mp3下载_喜马拉雅听 把时间花在迟疑、顾虑上,就是时空的浪费,马上行起来,就见面发颠覆的生成。