澳门新浦京娱乐场网站-www.146.net-新浦京娱乐场官网
做最好的网站

澳门新浦京娱乐场网站:中执行异步操作,的异

走进异步编制程序的世界 - 在 GUI 中实施异步操作

采用 async & await 的异步编制程序

【博主】反骨仔    【出处】   

应用 async & await 的异步编制程序

【博主】反骨仔    【出处】   

[C#] 在 GUI 中实践异步操作,

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

目录

  • 异步编制程序的简单介绍
  • 异步升高响应技术
  • 更便于编写的异步方法
  • 异步方法的调控流(核心)
  • 异步中的线程
  • async 和 await 修饰符
  • 重返类型和参数新闻
  • 命名的预订

 

目录

  • 异步编制程序的简单介绍
  • 异步进步响应才能
  • 更便于编写的异步方法
  • 异步方法的调控流(核心)
  • 异步中的线程
  • async 和 await 修饰符
  • 回来类型和参数音信
  • 取名的约定

 

在 GUI 中实践异步操作

 

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

1、异步编制程序的简要介绍

  通过行使异步编程,你可防止止品质瓶颈并巩固你的应用程序的完好响应手艺。

  从 VS 2011 初步,新引进了三个简化的措施,称为异步编制程序。我们在 >= .NET 四.5 大壮 Windows 运维时中选择异步,编写翻译器它会支持了大家降低了已经实行的高难度异步代码编写的劳作,但逻辑结构却就好像于同台代码。由此,大家仅需求举行一小部分编制程序的做事就足以博得异步编制程序的持有优点。

 

1、异步编程的简要介绍

  通过应用异步编制程序,你可防止止质量瓶颈并加强你的应用程序的完全响应技术。

  从 VS 二〇一二 开头,新引进了二个简化的秘诀,称为异步编程。大家在 >= .NET 四.5 竹秋 Windows 运维时中选用异步,编写翻译器它会拉拉扯扯了大家下落了已经举办的高难度异步代码编写的做事,但逻辑结构却就像是于同台代码。由此,大家仅必要张开一小部分编制程序的办事就足以拿走异步编程的享有优点。

 

 

异步编制程序](

解析异步方法]( WinForm 中怎么着施行异步操作。

 

二、异步提升响应技巧

  异步对或然引起短路的运动(如访问 Web 时),对 Web 能源的拜访临时过慢或延缓过高。若这种职分在一道进度中受阻,则整个应用程序必须等待响应实现。 在利用异步的长河中,我们的应用程序可继续试行不正视Web 财富的任何干活,并会直接等候绿灯的任务顺遂完成。

  那是一对卓绝的应用异步的应用场景,以及部分在 .NET >= 肆.伍 后新添的类库。

澳门新浦京娱乐场网站 1

  全体与用户分界面相关的操作经常共享贰个线程,所以采用异步对于利用 UI 线程的 App 来讲是不行首要的。

  如若说你的 App 全体操作都以贰头的,也正是说,当一个线程出现堵塞,别的线程都会并发堵塞,更严重的是, App 会结束响应。

澳门新浦京娱乐场网站 2

 

  使用异步方法时,App 将持续响应 UI。如:最大和最小化,不过效果依旧在后台实施(如:下载)。

 

2、异步升高响应本领

  异步对恐怕引起短路的位移(如访问 Web 时),对 Web 能源的走访不经常过慢或延迟过高。若这种任务在共同进程中受阻,则整个应用程序必须等待响应达成。 在使用异步的经过中,大家的应用程序可继续执行不正视Web 能源的此外干活,并会直接等候绿灯的任务顺遂实现。

  那是部分头一无二的行使异步的接纳场景,以及一些在 .NET >= 4.伍 后新增加的类库。

澳门新浦京娱乐场网站 3

  全体与用户分界面相关的操作平常共享一个线程,所以利用异步对于利用 UI 线程的 App 来讲是老大重大的。

  如若说你的 App 全部操作都是同步的,约等于说,当1个线程现身堵塞,别的线程都会油不过生堵塞,更严重的是, App 会停止响应。

澳门新浦京娱乐场网站 4

 

  使用异步方法时,App 将连续响应 UI。如:最大和最小化,不过效果依旧在后台试行(如:下载)。

 

目录

 

目录

  • 在 WinForm 中施行异步操作
  • 在 WinForm 中选取异步 拉姆da 表明式
  • 三个完好无损的 WinForm 程序
  • 另一种异步情势 - BackgroundWorker 类

 

三、更易于编写的异步方法

  C# 中的 async 和 await 关键字都以异步编制程序的基本。通过利用那多个器重字,大家就足以在 .NET 轻便成立异步方法。

  示例:

 1         /// <summary>
 2         /// 异步访问 Web 
 3         /// </summary>
 4         /// <returns></returns>
 5         /// <remarks>
 6         /// 方法签名的 3 要素:
 7         ///     ① async 修饰符
 8         ///     ② 返回类型 Task 或 Task<TResult>:这里的 Task<int> 表示 return 语句返回 int 类型
 9         ///     ③ 方法名以 Async 结尾
10         /// </remarks>
11         async Task<int> AccessTheWebAsync()
12         {
13             //记得 using System.Net.Http 哦
14             var client = new HttpClient();
15 
16             //执行异步方法 GetStringAsync
17             Task<string> getStringTask = client.GetStringAsync("http://www.google.com.hk/");
18 
19             //假设在这里执行一些非异步的操作
20             Do();
21 
22             //等待操作挂起方法 AccessTheWebAsync
23             //直到 getStringTask 完成,AccessTheWebAsync 方法才会继续执行
24             //同时,控制将返回到 AccessTheWebAsync 方法的调用方
25             //直到 getStringTask 完成后,将在这里恢复控制。
26             //然后从 getStringTask 拿到字符串结果
27             string urlContents = await getStringTask;
28 
29             //返回字符串的长度(int 类型)
30             return urlContents.Length;
31         }

 

  假如 AccessTheWebAsync 在调用 GetStringAsync() 时未有任何操作(如:代码中的 Do()),你能够用这样的措施来简化代码。

string urlContents = await client.GetStringAsync("http://www.google.com.hk/");

  

  简单总括:

  (一)方法具名包涵3个 async 修饰符。

  (二)遵照约定,异步方法的称号要求以“Async”后缀为最终。

  (叁)三种回到类型:

    ① Task<TResult>:返回 TResult 类型。

    贰Task:未有重回值,即重回值为 void。

    3void:只适用于异步事件管理程序。

  (肆)方法一般包蕴至少二个await 表达式,该表明式标识三个点,我们能够造成悬挂点,在该点上,直到等待的异步操作完毕,之后的艺术才干继续推行。 与此同一时候,该方法将挂起,并将调节权重临到点子的调用方。

  

  供给接纳异步方法的话,我们直接在系统内部选择所提供的首要字 async 和 await 就足以了,剩余的其他事情,就留给编写翻译器吧。 

 

叁、更便于编写的异步方法

  C# 中的 async 和 await 关键字都以异步编制程序的基本。通过选用那七个首要字,大家就可以在 .NET 轻巧创造异步方法。

  示例:

 1         /// <summary>
 2         /// 异步访问 Web 
 3         /// </summary>
 4         /// <returns></returns>
 5         /// <remarks>
 6         /// 方法签名的 3 要素:
 7         ///     ① async 修饰符
 8         ///     ② 返回类型 Task 或 Task<TResult>:这里的 Task<int> 表示 return 语句返回 int 类型
 9         ///     ③ 方法名以 Async 结尾
10         /// </remarks>
11         async Task<int> AccessTheWebAsync()
12         {
13             //记得 using System.Net.Http 哦
14             var client = new HttpClient();
15 
16             //执行异步方法 GetStringAsync
17             Task<string> getStringTask = client.GetStringAsync("http://www.google.com.hk/");
18 
19             //假设在这里执行一些非异步的操作
20             Do();
21 
22             //等待操作挂起方法 AccessTheWebAsync
23             //直到 getStringTask 完成,AccessTheWebAsync 方法才会继续执行
24             //同时,控制将返回到 AccessTheWebAsync 方法的调用方
25             //直到 getStringTask 完成后,将在这里恢复控制。
26             //然后从 getStringTask 拿到字符串结果
27             string urlContents = await getStringTask;
28 
29             //返回字符串的长度(int 类型)
30             return urlContents.Length;
31         }

 

  假设 AccessTheWebAsync 在调用 GetStringAsync() 时未有其余操作(如:代码中的 Do()),你能够用这么的艺术来简化代码。

string urlContents = await client.GetStringAsync("http://www.google.com.hk/");

  

  简单计算:

  (一)方法签字包含1个 async 修饰符。

  (二)依照预定,异步方法的名称必要以“Async”后缀为尾声。

  (三)3种回到类型:

    ① Task<TResult>:返回 TResult 类型。

    ②Task:未有重回值,即再次来到值为 void。

    3void:只适用于异步事件管理程序。

  (四)方法一般包蕴至少八个await 表明式,该表明式标志一个点,大家能够改为悬挂点,在该点上,直到等待的异步操作实现,之后的不二法门技巧继续试行。 与此同有的时候候,该措施将挂起,并将调控权重回到艺术的调用方。

  

  需求运用异步方法的话,大家一直在系统里头使用所提供的最主要字 async 和 await 就足以了,剩余的任何事情,就留给编写翻译器吧。 

 

壹、在 GUI 程序中施行异步操作

  上面通过窗体示例演示以下操作-点击按键后:一将标签内容改成:“Doing”,并将开关禁止使用(表示推行中);贰线程挂起3秒(模拟耗费时间操作);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

 

  开采的主题素材:好像未有成为“Doing”,并且拖动窗口的时候卡住不动了,3秒后突然变到想拖动到的岗位,并且文本变成“Complete”?

  【深入分析】GUI 程序在设计中须要具有的显得变化都不能够不在主 GUI 线程中形成,如点击事件和平运动动窗体。Windows 程序时经过 音讯来贯彻,音信放入音讯泵管理的音讯队列中。点击开关时,开关的Click音信放入新闻队列。音信泵从队列中移除该音信,并初叶拍卖点击事件的代码,即 btnDo_Click 事件的代码。btnDo_Click 事件会将触及行为的新闻放入队列,但在 btnDo_Click 时间管理程序退出前(线程挂起 3 秒退出前),音信都心有余而力不足奉行。接着全部行为举止都发生了,但速度太快肉眼辨识不了。

图壹-2 点击事件

图1-叁 点击事件具体实践进度

   【分析】如果 btnDo_Click 事件管理程序能先将前两条音讯压入队列,然后将和睦从Computer移出,在四秒后再将团结压入队列。那样能够维持响应,并确认保证具备的消息可以在线程挂起的岁月内被管理。


【原来的书文地址】 

 

] 在 GUI 中执行异步操作, 在 GUI 中实行异步操作 序 目录 1、在 GUI 程序中实施异步操作 下边通过窗体示例演示以下操作-点击开关后:...

1、在 WinForm 程序中施行异步操作

  上面通过窗体示例演示以下操作-点击开关后:

    1将按键禁用,并将标签内容改成:“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     }

  然则实行结果却是:

澳门新浦京娱乐场网站 5

图1-1

 

  【开采的难点】

    1好像一直不成为“Doing”?

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

    叁3秒后突然变到想拖动到的职位?

    ④还要文本变成“Complete”?

 

  【分析】GUI 程序在设计中供给有所的呈现变化都必须在主 GUI 线程中达成,如点击事件和运动窗体。Windows 程序时经过 音信来贯彻,音讯放入音信泵管理的音讯队列中。点击按键时,按键的Click音讯放入新闻队列。音讯泵从队列中移除该新闻,并初叶拍卖点击事件的代码,即 btnDo_Click 事件的代码。

  btnDo_Click 事件会将触及行为的新闻放入队列,但在 btnDo_Click 时间管理程序完全脱离前(线程挂起 三 秒退出前),新闻都不只怕施行。(3 秒后)接着全体行为举止都发出了,但速度太快肉眼不可能分辨才未有开采用国际标准和国外先进标准签改成“Doing”。

澳门新浦京娱乐场网站 6

图一-二 点击事件

澳门新浦京娱乐场网站 7

图壹-三 点击事件具体施行进程

  

  今后大家进入 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     }

澳门新浦京娱乐场网站 8

图1-4

  以往,正是本来希望见到的作用。

  【分析】btnDo_Click 事件管理程序先将前两条音讯压入队列,然后将协和从Computer移出,在3秒后(等待空闲职务成功后 Task.Delay )再将本身压入队列。那样能够有限支撑响应,并保管具有的新闻能够在线程挂起的日子内被管理。

 

四、异步方法的调节流(主旨)

  异步编制程序中最注重却不易懂的是调节流,即不一致格局间的切换。现在,请用1颗感恩的心来察看下图。

澳门新浦京娱乐场网站 9

  步骤解析:

  一 事件管理程序调用并等候 AccessTheWebAsync() 异步方法。

  贰 AccessTheWebAsync 创造 HttpClient 对象并调用它的 GetStringAsync 异步方法来下载网站内容。

  三要是 GetStringAsync 中发生了某种情状,该境况挂起了它的进度。或者必须等待网址下载或一些别样阻塞的位移。为幸免阻塞财富,GetStringAsync() 会将调控权出让给其调用方 AccessTheWebAsync。GetStringAsync 重返 Task,在这之中 TResult 为字符串,并且 AccessTheWebAsync 将职责分配给 getStringTask 变量。该职分表示调用 GetStringAsync 的正在开始展览的经过,在那之中承诺当职业成功时发出实际字符串值。

  肆 由于尚未等待 getStringTask,因而,AccessTheWebAsync 能够继续施行不借助于 GetStringAsync 得出最终结出的别样职分。该职务由对伙同方法 DoIndependentWork 的调用表示。

  5 DoIndependentWork 是达成其行事并赶回其调用方的联合签字方法。

  陆 AccessTheWebAsync 已变成工作,可以不受 getStringTask 的结果影响。 接下来,AccessTheWebAsync 需求计算并重临该下载字符串的尺寸,但该方法仅在全体字符串时手艺臆想该值。因而,AccessTheWebAsync 使用3个 await 运算符来挂起其速度,并把调控权交给调用 AccessTheWebAsync 的办法。AccessTheWebAsync 将 Task<int> 重返至调用方。 该职分表示对发出下载字符串长度的平头结果的一个承诺。

  【备注】要是 GetStringAsync(即 getStringTask)在 AccessTheWebAsync 等待前成功,则调节权会保留在 AccessTheWebAsync 中。 若是异步调用进度(getStringTask) 已变成,并且 AccessTheWebSync 不必等待最终结果,则挂起接下来回来到 AccessTheWebAsync,但那会变成费用的浪费。

  在调用方内部(要是那是二个事件管理程序),处理形式将继续。在等候结果前,调用方能够拓展不借助于于 AccessTheWebAsync 结果的别样干活,不然就需等候片刻。事件管理程序等待 AccessTheWebAsync,而 AccessTheWebAsync 等待 GetStringAsync。

  七 GetStringAsync 完成并生成二个字符串结果。 字符串结果不是通过你预期的不②法门调用 GetStringAsync 所重回的。(请牢记,此办法已在步骤 3中回到1个职责。)相反,字符串结果存款和储蓄在表示完毕措施 getStringTask 的天职业中学。 await 运算符从 getStringTask 中寻觅结果。赋值语句将追寻到的结果赋给 urlContents。

  八 当 AccessTheWebAsync 具备字符串结果时,该格局能够估测计算字符串长度。然后,AccessTheWebAsync 职业也将完毕,并且等待事件管理程序可继续运用。 

 

  你可以尝试考虑一下共同行为和异步行为之间的距离。当其职业成就时(第4 步)会回来一个一齐方法,但当其行事挂起时(第 3 步和第 6步),异步方法会重临八个职责值。在异步方法最后大功告成其行事时,职责会标识为已成功,而结果(尽管有)将积存在职务中。

 

4、异步方法的调整流(宗旨)

  异步编制程序中最入眼却不易懂的是调控流,即不一样方法间的切换。将来,请用壹颗感恩的心来察看下图。

澳门新浦京娱乐场网站 10

  步骤分析:

  1 事件管理程序调用并等待 AccessTheWebAsync() 异步方法。

  2 AccessTheWebAsync 成立 HttpClient 对象并调用它的 GetStringAsync 异步方法来下载网址内容。

  ③假诺 GetStringAsync 中发生了某种景况,本场所挂起了它的进度。大概必须等待网址下载或部分任何阻塞的运动。为幸免阻塞财富,GetStringAsync() 会将调节权出让给其调用方 AccessTheWebAsync。GetStringAsync 重临 Task,当中 TResult 为字符串,并且 AccessTheWebAsync 将职分分配给 getStringTask 变量。该职责表示调用 GetStringAsync 的正在进行的过程,个中承诺当专业成就时发出实际字符串值。

  四 由于并未有等待 getStringTask,因而,AccessTheWebAsync 能够继续执行不借助于 GetStringAsync 得出最后结出的别样职分。该职务由对伙同方法 DoIndependentWork 的调用表示。

  五 DoIndependentWork 是成功其事业并回到其调用方的1道方法。

  陆 AccessTheWebAsync 已产生工作,能够不受 getStringTask 的结果影响。 接下来,AccessTheWebAsync 须要总括并赶回该下载字符串的尺寸,但该办法仅在具有字符串时技艺揣测该值。因而,AccessTheWebAsync 使用七个 await 运算符来挂起其速度,并把调控权交给调用 AccessTheWebAsync 的方法。AccessTheWebAsync 将 Task<int> 重返至调用方。 该职务表示对爆发下载字符串长度的板寸结果的贰个答应。

  【备注】要是 GetStringAsync(即 getStringTask)在 AccessTheWebAsync 等待前产生,则调控权会保留在 AccessTheWebAsync 中。 倘诺异步调用进度(getStringTask) 已产生,并且 AccessTheWebSync 不必等待最后结出,则挂起接下来回来到 AccessTheWebAsync,但那会导致资金财产的浪费。

  在调用方内部(如果那是贰个事件处理程序),管理格局将承袭。在等待结果前,调用方能够拓展不借助于于 AccessTheWebAsync 结果的此外专门的职业,不然就需等候片刻。事件处理程序等待 AccessTheWebAsync,而 AccessTheWebAsync 等待 GetStringAsync。

  7 GetStringAsync 完成并生成2个字符串结果。 字符串结果不是经过你预期的艺术调用 GetStringAsync 所重返的。(请记住,此措施已在步骤 3中回到三个职分。)相反,字符串结果存款和储蓄在象征达成章程 getStringTask 的职分中。 await 运算符从 getStringTask 中探求结果。赋值语句将搜索到的结果赋给 urlContents。

  八 当 AccessTheWebAsync 具备字符串结果时,该方法能够总计字符串长度。然后,AccessTheWebAsync 工作也将成功,并且等待事件管理程序可承继应用。 

 

  你能够品尝思索一出手拉手行为和异步行为之间的差异。当其行事到位时(第4 步)会回去二个同台方法,但当其行事挂起时(第 三 步和第 6步),异步方法会再次来到三个职分值。在异步方法最后成就其行事时,职分会标识为已到位,而结果(若是有)将积攒在职务中。

 

 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     }

澳门新浦京娱乐场网站 11

 图1.1-1

  上述代码每施行一千次巡回就调用 Task.Yield 方法成立二个等候职分,让计算机有的时候间拍卖任何职务。该格局在 GUI 程序中是相比较有效的。

 

5、异步中的线程

  异步方法目的在于成为非阻塞操作。异步方法中的 await 表达式在守候的任务施行的还要不会阻塞当前线程。相反,await 表明式在继续实行时办法的别的部分并将调整权重回到异步方法的调用方。

  async 和 await 关键字不会产生制造别的线程。因为异步方法不会在其自己线程上运转,由此它无需三十二线程。唯有当方法处于活动状态时,该方式就要现阶段联合具名上下文中运营并使用线程上的日子。能够应用 Task.Run 将攻下大批量CPU 的行事移到后台线程,然而后台线程不会支援正在等候结果的长河变为可用状态。

  对于异步编制程序来讲,该基于异步的不贰法门优于差不离各类用例中的现成措施。具体来说,此格局比 BackgroundWorker 更适用于 IO 绑定的操作,因为此代码更简便且无需预防超过争用标准化。结合 Task.Run() 使用时,异步编制程序比 BackgroundWorker 更适用于 CPU 绑定的操作,因为异步编制程序将运维代码的和煦细节与 Task.Run 传输至线程池的办事分别开来。

 

五、异步中的线程

  异步方法目的在于成为非阻塞操作。异步方法中的 await 表明式在守候的任务施行的同有的时候候不会堵塞当前线程。相反,await 表明式在继续施行时方法的其他部分并将调节权重临到异步方法的调用方。

澳门新浦京娱乐场网站:中执行异步操作,的异步编程。  async 和 await 关键字不会导致成立别的线程。因为异步方法不会在其自己线程上运维,由此它没有须求二十八线程。只有当方法处于活动状态时,该方法将要时下一齐上下文中运作并动用线程上的岁月。能够采纳 Task.Run 将占用大量CPU 的劳作移到后台线程,然而后台线程不会拉拉扯扯正在等候结果的进度变为可用状态。

  对于异步编制程序来说,该基于异步的秘籍优于大概各样用例中的现存措施。具体来说,此措施比 BackgroundWorker 更适用于 IO 绑定的操作,因为此代码更简单且不须求防止超越争用标准。结合 Task.Run() 使用时,异步编制程序比 BackgroundWorker 更适用于 CPU 绑定的操作,因为异步编制程序将运维代码的协调细节与 Task.Run 传输至线程池的职业分别开来。

 

澳门新浦京娱乐场网站:中执行异步操作,的异步编程。贰、在 WinForm 中应用异步 拉姆da 表明式

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

 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     }

  依旧本来的配方,照旧纯熟的深意,照旧原本哪个窗口,变的只是内涵。

澳门新浦京娱乐场网站 12

图2-1

澳门新浦京娱乐场网站, 

六、async 和 await 修饰符

  当你利用 async 修饰符内定该方式为异步方法时:

  • 能够采取 await 来钦点悬挂点。await 运算符会告诉编写翻译器,异步方法唯有直到等待的异步进程进行到位,手艺三番五次透过该点往下实施。同一时间,调整权将重返至异步方法的调用方。await 表明式中异步方法在挂起后,若是该格局还从未施行到位并脱离,finally 块中的将不会实行。

  • 标识的异步方法本人能够经过调用它的主意开始展览等待。异步方法中国和东瀛常蕴涵1个或多少个await 运算符,当然,二个 await 表明式都不存在也不会招致编写翻译器错误,可是编写翻译器会爆发警告,该情势在实行的时候如故会遵照同步方法来实行,async 其实只是3个标志的效果而已,告诉编写翻译器他“应该”是一个异步方法。

 

六、async 和 await 修饰符

  当您采用 async 修饰符钦命该措施为异步方法时:

  • 能够利用 await 来钦命悬挂点。await 运算符会告诉编写翻译器,异步方法唯有直到等待的异步进程实行到位,技巧持续通过该点往下实践。同期,调整权将回到至异步方法的调用方。await 表明式中异步方法在挂起后,要是该措施还不曾实行到位并退出,finally 块中的将不会进行。

  • 标志的异步方法自己可以由此调用它的措施实行等待。异步方法中常见包罗一个或三个await 运算符,当然,叁个 await 表明式都不设有也不会导致编写翻译器错误,可是编写翻译器会发出警示,该办法在进行的时候仍旧会遵循同步方法来实行,async 其实只是二个标志的效劳而已,告诉编写翻译器他“应该”是2个异步方法。

 

3、二个总体的 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     }

澳门新浦京娱乐场网站 13

 图3-1

 

柒、再次回到类型和参数新闻

  在编写异步方法时,大家多方会选择Task 和 Task<TResult> 作为再次来到类型。

 

  示例:

 1         static async Task<Guid> Method1Async()  //Task<Guid>
 2         {
 3             var result = Guid.NewGuid();
 4 
 5             await Task.Delay(1);
 6 
 7             //这里返回一个 Guid 的类型
 8             return result;
 9         }
10 
11         static async Task Method2Async()  //Task
12         {
13             //Do...
14 
15             await Task.Delay(1);
16 
17             //Do...
18 
19             //这里没有 return 语句
20         }

 1             //调用 Method1Async
 2             //方式一
 3             Task<Guid> t1 = Method1Async();
 4             Guid guid1 = t1.Result;
 5 
 6             //方式二
 7             Guid guid2 = await Method1Async();
 8 
 9             //调用 Method2Async
10             //方式一
11             Task t2 = Method2Async();
12             await t2;
13 
14             //方式二
15             await Method2Async();

  每一种重回的任务表示正在进展的办事。职责可包裹有关异步进程景况的新闻,若是未中标,则最后会卷入来自进度的尾声结出,只怕是由该进程引发的老大。

 

  【疑问】那么 void 重回类型是在怎么状态下才使用的吗?

  首要用来异步的事件管理程序,异步事件管理程序经常作为异步程序的初阶点。void 重回类型告诉了编写翻译器,无需对她展开等待,并且,对于 void 重临类型的主意,大家也不知所厝对她开始展览充足的捕捉。

 

  异步方法不能在参数中注脚与使用 ref 和 out 关键字,但是异步方法能够调用包罗这一个参数的诀要。

 

七、重临类型和参数消息

  在编辑异步方法时,我们多方会采用Task 和 Task<TResult> 作为重临类型。

 

  示例:

 1         static async Task<Guid> Method1Async()  //Task<Guid>
 2         {
 3             var result = Guid.NewGuid();
 4 
 5             await Task.Delay(1);
 6 
 7             //这里返回一个 Guid 的类型
 8             return result;
 9         }
10 
11         static async Task Method2Async()  //Task
12         {
13             //Do...
14 
15             await Task.Delay(1);
16 
17             //Do...
18 
19             //这里没有 return 语句
20         }

 1             //调用 Method1Async
 2             //方式一
 3             Task<Guid> t1 = Method1Async();
 4             Guid guid1 = t1.Result;
 5 
 6             //方式二
 7             Guid guid2 = await Method1Async();
 8 
 9             //调用 Method2Async
10             //方式一
11             Task t2 = Method2Async();
12             await t2;
13 
14             //方式二
15             await Method2Async();

  各个重临的职务表示正在进展的劳作。职分可包裹有关异步进程境况的新闻,假诺未成功,则最终会卷入来自进度的末梢结果,大概是由该进度引发的足够。

 

  【疑问】那么 void 重临类型是在什么样境况下才使用的吧?

  首要用来异步的事件管理程序,异步事件管理程序平日作为异步程序的先导点。void 重返类型告诉了编译器,无需对他张开等待,并且,对于 void 重返类型的点子,我们也不能对她开始展览特别的捕捉。

 

  异步方法无法在参数中宣示与利用 ref 和 out 关键字,可是异步方法能够调用包罗那几个参数的点子。

 

肆、另一种异步格局 - BackgroundWorker 类

  与 async/await 区别的是,你不常候也许需求2个附加的线程,在后台持续完结某项任务,并时有的时候与主线程通讯,那时就要求用到 BackgroundWorker 类。首要用来 GUI 程序。

  书中的千万个言语不如1个简便的言传身教。

 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     }

澳门新浦京娱乐场网站 14

图4-1

 

8、命名的约定

  依据约定,使用 async 的法子都应有以“Async”作为后缀,如:DownloadAsync() 。不过,若是某一约定中的事件、基类或接口有任何的款式约定,则足以忽略上述约定。举例,不应有修改或重命名常用事件管理程序,如 btnOpen_Click。

 

八、命名的约定

  依照约定,使用 async 的办法都应当以“Async”作为后缀,如:DownloadAsync() 。可是,借使某1约定中的事件、基类或接口有其余的样式约定,则足以忽略上述约定。比方,不应有修改或重命名常用事件管理程序,如 btnOpen_Click。

 

 传送门

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

  • 发端接触 async/await 异步编制程序](

  上篇:《走进异步编制程序的世界 - 解析异步方法(上)》《[走进异步编制程序的世界

  • 剖析异步方法(下)](

 

 


传送门 

  1. 走进异步编制程序的世界 - 开端接触 async/await(推荐)

  2. 走进异步编制程序的社会风气 - 深入分析异步方法(上)

  3. 走进异步编制程序的世界 - 剖判异步方法(下)

  4. 走进异步编制程序的社会风气 - 在 GUI 中进行异步操作

 


【参考引用】微软官方文书档案图片

【参考】

 

传送门 

  1. 走进异步编制程序的世界 - 伊始接触 async/await(推荐)

  2. 走进异步编制程序的世界 - 深入分析异步方法(上)

  3. 走进异步编制程序的社会风气 - 剖判异步方法(下)

  4. 走进异步编制程序的世界 - 在 GUI 中实行异步操作

 


【仿照效法引用】微软官方文档图片

【参考】

 

【参考】《Illustrated C# 2012》

本文由澳门新浦京娱乐场网站发布于www.146.net,转载请注明出处:澳门新浦京娱乐场网站:中执行异步操作,的异