异步编制程序,走进异步编制程序的世界

走进异步编制程序的社会风气 – 剖析异步方法(上)

走进异步编制程序的社会风气 – 剖析异步方法(上)

一、简介

[C#] 异步编制程序,

  那是上篇《走进异步编制程序的社会风气 – 初步接触 async/await
异步编制程序》(入门)的第一章内容,首尽管与大家一块儿深远切磋下异步方法。

  本文需求明白委托的使用。

 

  那是上篇《走进异步编制程序的世界 – 起始接触 async/await
异步编制程序》(入门)的第一章内容,首若是与大家1块儿深刻切磋下异步方法。

  本文供给驾驭委托的施用。

 

  首先来看看.net的迈入中的各类阶段的风味:NET 与C#
的每一个版本公布都以有二个“大旨”。即:C#一.0托管代码→C#2.0泛型→C#3.0LINQ→C#四.0动态语言→C#4.5异步编程

解析异步方法

目录

  • 介绍异步方法

  • 控制流

  • await
    表达式

  • How
    裁撤异步操作

 

目录

  • 介绍异步方法

  • 控制流

  • await
    表达式

  • How
    撤废异步操作

 

 

  那是上篇《开头接触 async/await
异步编制程序》(入门)的第二章内容,主倘诺深刻领悟异步方法,提议大家先看入门篇,相当的短。

  本文须要掌握委托的接纳。

 

介绍异步方法

     异步方法:在施行到位前及时赶回调用方法,在调用方法继续实行的进度中达成职责。

     语法分析:

     (一)关键字:方法头使用 async
修饰。

     (2)须求:包蕴N(N>0) 个 await 表明式(不存在 await 表达式的话 IDE
会发出警告),表示供给异步实施的任务。【备注】谢谢 czcz1024 的校对与补偿:没有的话,就和常常方法一致举行了。

     (叁)重返类型:只能回去 3连串型(void、Task 和 Task<T>)。Task 和 Task<T>
标志重临的目的会在以往到位职业,表示调用方法和异步方法可以继续实施。

     (四)参数:数量不限。但无法运用 out
和 ref 关键字。

异步编制程序,走进异步编制程序的世界。     (5)命名约定:方法后缀名应以 Async
结尾。

     (6)其它:匿有名的模特式和 拉姆da
表明式也能够看作异步对象;async 是2个上下文关键字;关键字 async
必须在回去类型前。

 

亚洲必赢官网 1图一异步方法的简约结构图

  关于 async 关键字:

  壹在回去类型从前包括 async 关键字

  二它只是标记该情势包罗2个或八个 await
表明式,即,它自个儿不创制异步操作。

  叁它是上下文关键字,就可以作为变量名。

 

  将来先来大致分析一下这三种回到值类型:void、Task 和 Task<T>

  (一)Task<T>:调用方法要从调用中获得2个T 类型的值,异步方法的归来类型就非得是Task<T>。调用方法从 Task 的
Result 属性获取的正是 T 类型的值。

亚洲必赢官网 2亚洲必赢官网 3

 1         private static void Main(string[] args)
 2         {
 3             Task<int> t = Calculator.AddAsync(1, 2);
 4 
 5             //一直在干活
 6 
 7             Console.WriteLine($"result: {t.Result}");
 8 
 9             Console.Read();
10         }

Program.cs

亚洲必赢官网 4亚洲必赢官网 5

 1     internal class Calculator
 2     {
 3         private static int Add(int n, int m)
 4         {
 5             return n + m;
 6         }
 7 
 8         public static async Task<int> AddAsync(int n, int m)
 9         {
10             int val = await Task.Run(() => Add(n, m));
11 
12             return val;
13         }
14     }

View Code 

亚洲必赢官网 6

图2

亚洲必赢官网 7

图3

 

  (二)Task:调用方法不必要从异步方法中取重返值,不过指望检查异步方法的情状,那么能够挑选能够回去
Task 类型的目的。不过,即使异步方法中蕴藏 return
语句,也不会重返任何事物。

亚洲必赢官网 8亚洲必赢官网 9

 1         private static void Main(string[] args)
 2         {
 3             Task t = Calculator.AddAsync(1, 2);
 4 
 5             //一直在干活
 6 
 7             t.Wait();
 8             Console.WriteLine("AddAsync 方法执行完成");
 9 
10             Console.Read();
11         }

Program.cs

亚洲必赢官网 10亚洲必赢官网 11

 1     internal class Calculator
 2     {
 3         private static int Add(int n, int m)
 4         {
 5             return n + m;
 6         }
 7 
 8         public static async Task AddAsync(int n, int m)
 9         {
10             int val = await Task.Run(() => Add(n, m));
11             Console.WriteLine($"Result: {val}");
12         }
13     }

View Code

 

亚洲必赢官网 12

 

图4

亚洲必赢官网 13

图5

     

  (三)void:调用方法实践异步方法,但又不供给做越来越的相互。 

亚洲必赢官网 14亚洲必赢官网 15

 1         private static void Main(string[] args)
 2         {
 3             Calculator.AddAsync(1, 2);
 4 
 5             //一直在干活
 6 
 7             Thread.Sleep(1000); //挂起1秒钟
 8             Console.WriteLine("AddAsync 方法执行完成");
 9 
10             Console.Read();
11         }

Program.cs

亚洲必赢官网 16亚洲必赢官网 17

 1     internal class Calculator
 2     {
 3         private static int Add(int n, int m)
 4         {
 5             return n + m;
 6         }
 7 
 8         public static async void AddAsync(int n, int m)
 9         {
10             int val = await Task.Run(() => Add(n, m));
11             Console.WriteLine($"Result: {val}");
12         }
13     }

Calculator.cs

亚洲必赢官网 18

图6

亚洲必赢官网 19

图7

 

介绍异步方法

     异步方法:在执行到位前及时回到调用方法,在调用方法继续施行的经过中形成任务。

     语法分析:

     (1)关键字:方法头使用 async
修饰。

     (2)供给:包涵N(N>0) 个 await 表明式(不存在 await 表达式的话 IDE
会发出警示),表示必要异步执行的任务。【备注】感激 czcz1024 的改进与增补:未有的话,就和普通方法同样举行了。

     (3)再次来到类型:只好回去 3种档次(void、Task 和 Task<T>)。Task 和 Task<T>
标志重临的靶子会在前天完结工作,表示调用方法和异步方法能够继续实施。

     (四)参数:数量不限。但不能够利用 out
和 ref 关键字。

     (5)命名约定:方法后缀名应以 Async
结尾。

     (6)此外:匿超级模特式和 拉姆da
表达式也得以看成异步对象;async 是一个上下文关键字;关键字 async
必须在回来类型前。

 

亚洲必赢官网 20图一 异步方法的简单结构图

  关于 async 关键字:

  壹在再次回到类型在此之前包括 async 关键字

  二它只是标志该办法蕴含一个或多少个 await
表明式,即,它本人不创制异步操作。

  叁它是上下文关键字,就能够作为变量名。

 

  未来先来不难解析一下这两种回到值类型:void、Task 和 Task<T>

  (1)Task<T>:调用方法要从调用中获取一个T 类型的值,异步方法的回来类型就务须是Task<T>。调用方法从 Task 的
Result 属性获取的就是 T 类型的值。

亚洲必赢官网 21亚洲必赢官网 22

 1         private static void Main(string[] args)
 2         {
 3             Task<int> t = Calculator.AddAsync(1, 2);
 4 
 5             //一直在干活
 6 
 7             Console.WriteLine($"result: {t.Result}");
 8 
 9             Console.Read();
10         }

Program.cs

亚洲必赢官网 23亚洲必赢官网 24

 1     internal class Calculator
 2     {
 3         private static int Add(int n, int m)
 4         {
 5             return n + m;
 6         }
 7 
 8         public static async Task<int> AddAsync(int n, int m)
 9         {
10             int val = await Task.Run(() => Add(n, m));
11 
12             return val;
13         }
14     }

View Code 

亚洲必赢官网 25

图2

亚洲必赢官网 26

图3

 

  (2)Task:调用方法不须要从异步方法中取重临值,可是指望检查异步方法的事态,那么能够选拔能够回到
Task 类型的目的。可是,就算异步方法中包含 return
语句,也不会回去任丁芯西。

亚洲必赢官网 27亚洲必赢官网 28

 1         private static void Main(string[] args)
 2         {
 3             Task t = Calculator.AddAsync(1, 2);
 4 
 5             //一直在干活
 6 
 7             t.Wait();
 8             Console.WriteLine("AddAsync 方法执行完成");
 9 
10             Console.Read();
11         }

Program.cs

亚洲必赢官网 29亚洲必赢官网 30

 1     internal class Calculator
 2     {
 3         private static int Add(int n, int m)
 4         {
 5             return n + m;
 6         }
 7 
 8         public static async Task AddAsync(int n, int m)
 9         {
10             int val = await Task.Run(() => Add(n, m));
11             Console.WriteLine($"Result: {val}");
12         }
13     }

View Code

 

亚洲必赢官网 31

 

图4

亚洲必赢官网 32

图5

     

  (三)void:调用方法实践异步方法,但又不需求做进一步的互动。 

亚洲必赢官网 33亚洲必赢官网 34

 1         private static void Main(string[] args)
 2         {
 3             Calculator.AddAsync(1, 2);
 4 
 5             //一直在干活
 6 
 7             Thread.Sleep(1000); //挂起1秒钟
 8             Console.WriteLine("AddAsync 方法执行完成");
 9 
10             Console.Read();
11         }

Program.cs

亚洲必赢官网 35亚洲必赢官网 36

 1     internal class Calculator
 2     {
 3         private static int Add(int n, int m)
 4         {
 5             return n + m;
 6         }
 7 
 8         public static async void AddAsync(int n, int m)
 9         {
10             int val = await Task.Run(() => Add(n, m));
11             Console.WriteLine($"Result: {val}");
12         }
13     }

Calculator.cs

亚洲必赢官网 37

图6

亚洲必赢官网 38

图7

 

  上边作者来大约的牵线一下异步编程:异步编程,在 .NET Framework 四.五 和
Windows 运维时采纳异步协理。
编写翻译器可实践开拓职员曾举办的高难度工作,且应用程序保留了贰个类似于1块代码的逻辑结构。
由此,你只需做一小部分职业就足以赢得异步编程的享有好处。 

目录

 

一、控制流

     异步方法的组织可拆分成多个例外的区域:

     (一)表达式此前的壹些:从点子头到第二个await 表明式之间的享有代码。

     (二)await
表明式:将被异步实践的代码。

     (3)表明式之后的有个别:await
表达式的持续部分。

 亚洲必赢官网 39

  图1-1

 

  该异步方法施行流程:从await表达式以前的位置开头,同步实施到第二个await,标志着第二有些举行实现,①般的话此时 await 工作还没到位。当await
任务成功后,该措施将继承联合施行后续部分。在施行的继续部分中,即使如故存在
await,就再一次上述进度。

  当达到 await
表明式时,线程将从异步方法再次回到到调用方法。即使异步方法的归来类型为 Task
或 Task<T>,会创建三个 Task 对象,标志要求异步达成的职务,然后将
Task 重回来调用方法。

 

亚洲必赢官网 40

  图1-2

  异步方法的调整流:

  壹异步实施 await 表明式的空闲职分。

  贰await 表明式实施到位,继续试行后续部分。如再碰到 await
表达式,按一样情形张开始拍录卖。

  三达到末尾或碰到 return 语句时,根据重临类型能够分三种景况:

    a.void:退出调节流。

    b.Task:设置
Task 的性质并脱离。

    c.Task<T>:设置 Task
的质量和再次回到值(Result 属性)并脱离。

  四还要,调用方法将继续实施,从异步方法获得 Task
对象。供给值的时候,会停顿等到 Task 对象的 Result
属性被赋值才会继续实施。

 

  【难点】

  一先是次蒙受 await
所再次来到对象的品类。那几个重返类型便是一块方法头的回到类型,跟 await
表达式的再次回到值未有涉及。

  二达到异步方法的最终或蒙受 return
语句,它并从未真的的归来二个值,而是退出了该格局。

 

一、控制流

     异步方法的布局可拆分成四个例外的区域:

     (一)表明式以前的部分:从章程头到首个await 表达式之间的富有代码。

     (二)await
表明式:将被异步推行的代码。

     (三)表明式之后的有个别:await
表达式的持续部分。

 亚洲必赢官网 41

  图1-1

 

  该异步方法实践流程:从await表达式以前的地点初叶,同步执行到第八个await,标志着第一有个别进行完结,一般的话此时 await 工作还没到位。当await
任务成功后,该办法将承接联合实践后续部分。在实践的继续部分中,假设依然存在
await,就再一次上述进度。

  当到达 await
表明式时,线程将从异步方法重临到调用方法。假设异步方法的回来类型为 Task
或 Task<T>,会创制3个 Task 对象,标记需求异步完毕的天职,然后将
Task 重回来调用方法。

 

亚洲必赢官网 42

  图1-2

  异步方法的调整流:

  壹异步奉行 await 表明式的空余职分。

  二await 表明式推行到位,继续试行后续部分。如再遇上 await
表明式,按一样境况开始展览拍卖。

  三到达末尾或蒙受 return 语句时,依据返回类型能够分三种情状:

    a.void:退出调整流。

    b.Task:设置
Task 的习性并退出。

    c.Task<T>:设置 Task
的性质和重临值(Result 属性)并退出。

  4还要,调用方法将继续实践,从异步方法得到 Task
对象。要求值的时候,会搁浅等到 Task 对象的 Result
属性被赋值才会继续实行。

 

  【难点】

  壹先是次相见 await
所重返对象的档次。那个再次回到类型正是1块方法头的归来类型,跟 await
表明式的重临值未有涉及。

  二到达异步方法的尾声或蒙受 return
语句,它并不曾真的的回到二个值,而是退出了该措施。

 

 

介绍异步方法

   
 异步方法:在施行到位前及时重返调用方法,在调用方法继续实行的经过中完毕职责。
     语法分析:      (一)关键字:方法头使用 async 修饰。    
 (二)需要:包括 N(N>0) 个 await 表达式(不存在 await 表明式的话
IDE
会发出警示),表示必要异步实施的职责。【备注】多谢 czcz拾2肆 的校正与互补:未有的话,就和常见方法同样进行了。
     (三)重临类型:只好回到 叁 连串型(void、Task 和
Task<T>)。Task 和 Task<T>
标志重临的靶子会在前几日到位工作,表示调用方法和异步方法能够继续实施。    
 (四)参数:数量不限。但无法使用 out 和 ref 关键字。    
 (五)命名约定:方法后缀名应以 Async 结尾。      (6)别的:匿名格局和
Lambda 表明式也足以看成异步对象;async 是二个上下文关键字;关键字 async
必须在再次来到类型前。     关于 async 关键字:

  一在再次来到类型从前包涵 async 关键字

  二它只是标记该方法包括2个或两个 await
表明式,即,它本身不创建异步操作。

  叁它是上下文关键字,就能够作为变量名。

 

  现在先来第3分析一下那三种回到值类型:void、Task 和 Task<T>

  (1)Task<T>:调用方法要从调用中获取2个 T
类型的值,异步方法的回到类型就亟须是Task<T>。调用方法从 Task 的
Result 属性获取的正是 T 类型的值。

亚洲必赢官网 43 1 private
static void Main(string[] args) 二 { 三 Task<int> t =
Calculator.AddAsync(一, 二); 四 伍 //一贯在办事 陆 七Console.WriteLine($”result: {t.Result}”); 8 九 Console.Read(); 10 } Program.cs
亚洲必赢官网 44 1 internal
class Calculator 2 { 3 private static int Add(int n, int m) 4 { 5 return
n + m; 6 } 7 8 public static async Task<int> AddAsync(int n, int
m) 9 { 10 int val = await Task.Run(() => Add(n, m)); 11 12 return
val; 13 } 14 } View Code 

 

  (二)Task:调用方法不必要从异步方法中取再次回到值,不过期望检查异步方法的动静,那么能够选用能够回到
Task 类型的对象。可是,纵然异步方法中隐含 return
语句,也不会回来任马建波西。

亚洲必赢官网 45 1 private
static void Main(string[] args) 2 { 叁 Task t = Calculator.AddAsync(1,
贰); 肆 5 //一贯在办事 陆 柒 t.Wait(); 八 Console.WriteLine(“AddAsync
方法实践到位”); 玖 拾 Console.Read(); 11 } Program.cs
亚洲必赢官网 46 1 internal
class Calculator 2 { 3 private static int Add(int n, int m) 4 { 5 return
n + m; 6 } 7 8 public static async Task AddAsync(int n, int m) 9 { 10
int val = await Task.Run(() => Add(n, m)); 11
Console.WriteLine($”Result: {val}”); 12 } 13 } View Code

亚洲必赢官网 47

图4

亚洲必赢官网 48

图5

     

  (三)void:调用方法试行异步方法,但又不要求做进一步的并行。 

亚洲必赢官网 49 1 private
static void Main(string[] args) 二 { 3 Calculator.AddAsync(一, 贰); 肆 5
//一贯在做事 陆 七 Thread.Sleep(1000); //挂起1分钟 八Console.WriteLine(“AddAsync 方法实践到位”); 玖 十 Console.Read(); 1一 }
Program.cs
亚洲必赢官网 50 1 internal
class Calculator 2 { 3 private static int Add(int n, int m) 4 { 5 return
n + m; 6 } 7 8 public static async void AddAsync(int n, int m) 9 { 10
int val = await Task.Run(() => Add(n, m)); 11
Console.WriteLine($”Result: {val}”); 12 } 13 } Calculator.cs

亚洲必赢官网 51

图6

亚洲必赢官网 52

图7

 

二、await 表达式

  await 表明式钦定了2个异步实践的天职。暗中同意意况,该任务在近来线程异步推行。

  每三个职责就是七个 awaitable 类的实例。awaitable 类型指包括GetAwaiter() 方法的门类。

  实际上,你并不供给营造友好的 awaitable,壹般只供给使用 Task
类,它正是 awaitable。

  最简便易行的主意是在点子中采取Task.Run() 来创制二个 Task。【注意】它是在不相同的线程上实施措施。

 

  让大家壹并来看望示例。

亚洲必赢官网 53亚洲必赢官网 54

 1     internal class Program
 2     {
 3         private static void Main(string[] args)
 4         {
 5             var t = Do.GetGuidAsync();
 6             t.Wait();
 7 
 8             Console.Read();
 9         }
10 
11 
12         private class Do
13         {
14             /// <summary>
15             /// 获取 Guid
16             /// </summary>
17             /// <returns></returns>
18             private static Guid GetGuid()   //与Func<Guid> 兼容
19             {
20                 return Guid.NewGuid();
21             }
22 
23             /// <summary>
24             /// 异步获取 Guid
25             /// </summary>
26             /// <returns></returns>
27             public static async Task GetGuidAsync()
28             {
29                 var myFunc = new Func<Guid>(GetGuid);
30                 var t1 = await Task.Run(myFunc);
31 
32                 var t2 = await Task.Run(new Func<Guid>(GetGuid));
33 
34                 var t3 = await Task.Run(() => GetGuid());
35 
36                 var t4 = await Task.Run(() => Guid.NewGuid());
37 
38                 Console.WriteLine($"t1: {t1}");
39                 Console.WriteLine($"t2: {t2}");
40                 Console.WriteLine($"t3: {t3}");
41                 Console.WriteLine($"t4: {t4}");
42             }
43         }
44     }

View Code

亚洲必赢官网 55

图2-1

亚洲必赢官网 56

图2-2

   上面 肆 个 Task.Run() 都以行使了 Task Run(Func<TReturn> func)
情势来一贯或直接调用 Guid.NewGuid()。

 

  Task.Run() 帮助 四 中差别的嘱托项目所表示的办法:Action、Func<TResult>、Func<Task>
和 Func<Task<TResult>>

亚洲必赢官网 57亚洲必赢官网 58

 1     internal class Program
 2     {
 3         private static void Main(string[] args)
 4         {
 5             var t = Do.GetGuidAsync();
 6             t.Wait();
 7 
 8             Console.Read();
 9         }
10 
11         private class Do
12         {
13             public static async Task GetGuidAsync()
14             {
15                 await Task.Run(() => { Console.WriteLine(Guid.NewGuid()); });   //Action
16 
17                 Console.WriteLine(await Task.Run(() => Guid.NewGuid()));    //Func<TResult>
18 
19                 await Task.Run(() => Task.Run(() => { Console.WriteLine(Guid.NewGuid()); }));   //Func<Task>
20 
21                 Console.WriteLine(await Task.Run(() => Task.Run(() => Guid.NewGuid())));    //Func<Task<TResult>>
22             }
23         }
24     }

View Code

亚洲必赢官网 59

图2-三 Task.Run() 方法的重载

 

二、await 表达式

  await 表明式指定了二个异步实施的职责。私下认可情状,该职分在脚下线程异步推行。

  每3个职分正是1个 awaitable 类的实例。awaitable 类型指包涵GetAwaiter() 方法的花色。

  实际上,你并不需求创设筑组织调的 awaitable,一般只要求选择 Task
类,它正是 awaitable。

  最简易的方法是在措施中应用
Task.Run() 来成立3个 Task。【注意】它是在分化的线程上实行方式。

 

  让大家壹块来看看示例。

亚洲必赢官网 60亚洲必赢官网 61

 1     internal class Program
 2     {
 3         private static void Main(string[] args)
 4         {
 5             var t = Do.GetGuidAsync();
 6             t.Wait();
 7 
 8             Console.Read();
 9         }
10 
11 
12         private class Do
13         {
14             /// <summary>
15             /// 获取 Guid
16             /// </summary>
17             /// <returns></returns>
18             private static Guid GetGuid()   //与Func<Guid> 兼容
19             {
20                 return Guid.NewGuid();
21             }
22 
23             /// <summary>
24             /// 异步获取 Guid
25             /// </summary>
26             /// <returns></returns>
27             public static async Task GetGuidAsync()
28             {
29                 var myFunc = new Func<Guid>(GetGuid);
30                 var t1 = await Task.Run(myFunc);
31 
32                 var t2 = await Task.Run(new Func<Guid>(GetGuid));
33 
34                 var t3 = await Task.Run(() => GetGuid());
35 
36                 var t4 = await Task.Run(() => Guid.NewGuid());
37 
38                 Console.WriteLine($"t1: {t1}");
39                 Console.WriteLine($"t2: {t2}");
40                 Console.WriteLine($"t3: {t3}");
41                 Console.WriteLine($"t4: {t4}");
42             }
43         }
44     }

View Code

亚洲必赢官网 62

图2-1

亚洲必赢官网 63

图2-2

   上边 四 个 Task.Run() 都以利用了 Task Run(Func<TReturn> func)
方式来一向或直接调用 Guid.NewGuid()。

 

  Task.Run() 帮忙 四 中不相同的信托项目所表示的法子:Action、Func<TResult>、Func<Task>
和 Func<Task<TResult>>

亚洲必赢官网 64亚洲必赢官网 65

 1     internal class Program
 2     {
 3         private static void Main(string[] args)
 4         {
 5             var t = Do.GetGuidAsync();
 6             t.Wait();
 7 
 8             Console.Read();
 9         }
10 
11         private class Do
12         {
13             public static async Task GetGuidAsync()
14             {
15                 await Task.Run(() => { Console.WriteLine(Guid.NewGuid()); });   //Action
16 
17                 Console.WriteLine(await Task.Run(() => Guid.NewGuid()));    //Func<TResult>
18 
19                 await Task.Run(() => Task.Run(() => { Console.WriteLine(Guid.NewGuid()); }));   //Func<Task>
20 
21                 Console.WriteLine(await Task.Run(() => Task.Run(() => Guid.NewGuid())));    //Func<Task<TResult>>
22             }
23         }
24     }

View Code

亚洲必赢官网 66

图二-三 Task.Run() 方法的重载

 

  所谓的异步编制程序是应用CPU空闲时间和多核的个性,它所再次来到的Task或Task<TResult>是对await的1个承诺,当职分实行达成后赶回三个结实给接收者。那里看到这么些只怕各位不太领悟,无妨,上面会有讲授。

一、控制流

     异步方法的结构可拆分成八个分歧的区域:    
 (一)表明式以前的有的:从章程头到第3个 await 表明式之间的兼具代码。  
   (二)await 表达式:将被异步执行的代码。    
 (3)表明式之后的1对:await 表明式的一而再部分。   壹 internal class
Program 贰 { 三 private static void Main(string[]亚洲必赢官网 , args) 4 { 5 var t =
Do.GetGuidAsync(); 陆 t.Wait(); 柒 八 Console.Read(); 玖 } 10 11 1贰 private
class Do 壹3 { 1四 /// <summary> 一伍 /// 获取 Guid 1六 ///
</summary> 一柒 /// <returns></returns> 18 private
static Guid GetGuid() //与Func<Guid> 包容 1九 { 20 return
Guid.NewGuid(); 二壹 } 2二 二三 /// <summary> 二四 /// 异步获取 Guid 25
/// </summary> 二陆 /// <returns></returns> 27 public
static async Task GetGuidAsync() 2八 { 2玖 var myFunc = new
Func<Guid>(GetGuid); 30 var t壹 = await Task.Run(myFunc); 3一 3二 var
t2 = await Task.Run(new Func<Guid>(GetGuid)); 33 3四 var t3 = await
Task.Run(() => GetGuid()); 35 3陆 var t4 = await Task.Run(() =>
Guid.NewGuid()); 三七 3八 Console.WriteLine($”t一: {t壹}”); 39Console.WriteLine($”t贰: {t贰}”); 40 Console.WriteLine($”t三: {t3}”); 41Console.WriteLine($”t4: {t四}”); 4二 } ④三 } 4四 } View Code

图2-1

图2-2

   下面 4 个 Task.Run() 都是接纳了 Task Run(Func<TReturn> func)
格局。

 

  Task.Run() 援救 四中分歧的信托项目所代表的不二等秘书诀:Action、Func<TResult>、Func<Task>
和 Func<Task<TResult>>

亚洲必赢官网 67 1 internal
class Program 2 { 3 private static void Main(string[] args) 4 { 5 var
t = Do.GetGuidAsync(); 6 t.Wait(); 7 8 Console.Read(); 9 } 10 11 private
class Do 12 { 13 public static async Task GetGuidAsync() 14 { 15 await
Task.Run(() => { Console.WriteLine(Guid.NewGuid()); }); //Action 16
17 Console.WriteLine(await Task.Run(() => Guid.NewGuid()));
//Func<TResult> 18 19 await Task.Run(() => Task.Run(() => {
Console.WriteLine(Guid.NewGuid()); })); //Func<Task> 20 21
Console.WriteLine(await Task.Run(() => Task.Run(() =>
Guid.NewGuid()))); //Func<Task<TResult>> 22 } 23 } 24 }
View Code

 

3、How 打消异步操作

   CancellationToken 和 CancellationTokenSource
那八个类允许你甘休推行异步方法。

  (一)CancellationToken
对象涵盖职责是或不是被撤废的音信;假设该目的的性质 IsCancellationRequested

true,职责需终止操作并回到;该指标操作是不可逆的,且不得不选用(修改)1次,即该对象内的 IsCancellationRequested
属性棉被服装置后,就不能够改变。

  (二)CancellationTokenSource 可创制 CancellationToken
对象,调用 CancellationTokenSource 对象的 Cancel
方法,会使该对象的 CancellationToken 属性 IsCancellationRequested 设置为
true。

  【注意】调用 CancellationTokenSource
对象的 Cancel
方法,并不会进行撤除操作,而是会将该目的的 CancellationToken
属性 IsCancellationRequested 设置为 true。

 

  示例

亚洲必赢官网 68亚洲必赢官网 69

 1     internal class Program
 2     {
 3         private static void Main(string[] args)
 4         {
 5             CancellationTokenSource source = new CancellationTokenSource();
 6             CancellationToken token = source.Token;
 7 
 8             var t = Do.ExecuteAsync(token);
 9 
10             //Thread.Sleep(3000);   //挂起 3 秒
11             //source.Cancel();    //传达取消请求
12 
13             t.Wait(token);  //等待任务执行完成
14             Console.WriteLine($"{nameof(token.IsCancellationRequested)}: {token.IsCancellationRequested}");
15 
16             Console.Read();
17         }
18 
19 
20     }
21 
22     internal class Do
23     {
24         /// <summary>
25         /// 异步执行
26         /// </summary>
27         /// <param name="token"></param>
28         /// <returns></returns>
29         public static async Task ExecuteAsync(CancellationToken token)
30         {
31             if (token.IsCancellationRequested)
32             {
33                 return;
34             }
35 
36             await Task.Run(() => CircleOutput(token), token);
37         }
38 
39         /// <summary>
40         /// 循环输出
41         /// </summary>
42         /// <param name="token"></param>
43         private static void CircleOutput(CancellationToken token)
44         {
45             Console.WriteLine($"{nameof(CircleOutput)} 方法开始调用:");
46 
47             const int num = 5;
48             for (var i = 0; i < num; i++)
49             {
50                 if (token.IsCancellationRequested)  //监控 CancellationToken
51                 {
52                     return;
53                 }
54 
55                 Console.WriteLine($"{i + 1}/{num} 完成");
56                 Thread.Sleep(1000);
57             }
58         }
59     }

View Code

亚洲必赢官网 70

图3-1

亚洲必赢官网 71

图3-贰 注释两行代码

亚洲必赢官网 72

图3-叁:图三-一和图三-二的进行结果(注释两行代码)

  上海教室是不调用 Cancel() 方法的结果图,不会撤除职责的进行。

 

  下图在 3 秒后调用 Cancel() 方法撤废职务的进行:

亚洲必赢官网 73

图三-4:去掉注释

亚洲必赢官网 74

图三-伍:图三-一和图三-四的实行结果(去掉注释)

 

3、How 撤消异步操作

   CancellationToken 和 CancellationTokenSource
那多少个类允许你打住实行异步方法。

  (一)CancellationToken
对象涵盖职责是不是被注销的音讯;假诺该指标的性质 IsCancellationRequested

true,义务需终止操作并回到;该对象操作是不可逆的,且只好选拔(修改)3次,即该目的内的 IsCancellationRequested
属性被设置后,就不可能退换。

  (2)CancellationTokenSource 可成立 CancellationToken
对象,调用 CancellationTokenSource 对象的 Cancel
方法,会使该指标的 CancellationToken 属性 IsCancellationRequested 设置为
true。

  【注意】调用 CancellationTokenSource
对象的 Cancel
方法,并不会实施撤除操作,而是会将该对象的 CancellationToken
属性 IsCancellationRequested 设置为 true。

 

  示例

亚洲必赢官网 75亚洲必赢官网 76

 1     internal class Program
 2     {
 3         private static void Main(string[] args)
 4         {
 5             CancellationTokenSource source = new CancellationTokenSource();
 6             CancellationToken token = source.Token;
 7 
 8             var t = Do.ExecuteAsync(token);
 9 
10             //Thread.Sleep(3000);   //挂起 3 秒
11             //source.Cancel();    //传达取消请求
12 
13             t.Wait(token);  //等待任务执行完成
14             Console.WriteLine($"{nameof(token.IsCancellationRequested)}: {token.IsCancellationRequested}");
15 
16             Console.Read();
17         }
18 
19 
20     }
21 
22     internal class Do
23     {
24         /// <summary>
25         /// 异步执行
26         /// </summary>
27         /// <param name="token"></param>
28         /// <returns></returns>
29         public static async Task ExecuteAsync(CancellationToken token)
30         {
31             if (token.IsCancellationRequested)
32             {
33                 return;
34             }
35 
36             await Task.Run(() => CircleOutput(token), token);
37         }
38 
39         /// <summary>
40         /// 循环输出
41         /// </summary>
42         /// <param name="token"></param>
43         private static void CircleOutput(CancellationToken token)
44         {
45             Console.WriteLine($"{nameof(CircleOutput)} 方法开始调用:");
46 
47             const int num = 5;
48             for (var i = 0; i < num; i++)
49             {
50                 if (token.IsCancellationRequested)  //监控 CancellationToken
51                 {
52                     return;
53                 }
54 
55                 Console.WriteLine($"{i + 1}/{num} 完成");
56                 Thread.Sleep(1000);
57             }
58         }
59     }

View Code

亚洲必赢官网 77

图3-1

亚洲必赢官网 78

图三-贰 注释两行代码

亚洲必赢官网 79

图三-叁:图3-1和图三-二的奉行结果(注释两行代码)

  上海教室是不调用 Cancel() 方法的结果图,不会吊销职分的实施。

 

  下图在 3 秒后调用 Cancel() 方法撤废任务的实行:

亚洲必赢官网 80

图3-肆:去掉注释

亚洲必赢官网 81

图三-5:图叁-一和图三-四的实施结果(去掉注释)

 

 

叁、撤废异步操作

 

小结

  • 介绍异步方法的语法、三种不相同的回来值类型(void、Task 和
    Task<T>)和决定流程等。
  • 简言之常用的异步试行措施:Task.Run()。【注意】它是在分裂的线程上实行情势。
  • 何以裁撤异步操作。

 

小结

  • 介绍异步方法的语法、三种差别的归来值类型(void、Task 和
    Task<T>)和调节流程等。
  • 粗略常用的异步实行办法:Task.Run()。【注意】它是在区别的线程上实行措施。
  • 什么打消异步操作。

 

二、使用验证

肆、非凡处理

 

传送门

  入门:《开班接触 async/await
异步编程》

  补充篇:《走进异步编制程序的世界 –
剖析异步方法(下)》

  GUI 篇:《走进异步编制程序的世界 – 在 GUI
中试行异步操作》

 


初稿链接:

 【参考】《Illustrated C# 2012》

传送门

  入门:《开首接触 async/await
异步编制程序》

  补充篇:《走进异步编制程序的世界 –
剖析异步方法(下)》

  GUI 篇:《走进异步编制程序的社会风气 – 在 GUI
中实行异步操作》

 


原稿链接:

 【参考】《Illustrated C# 2012》

格局具名蕴含贰个 Async 或 async 修饰符。

伍、在调用方法中联手地等待职责

 

 

6、在异步方法中异步地等候职责

 

依照约定,异步方法的称号以“Async”后缀结尾。

七、Task.Delay 方法

 

 

小结

 

回去类型为下列项目之1:

传送门

  入门:《初阶接触 async/await 异步编制程序》

 


 

–这是预览版本,最后整理完核查后将放上首页,不便之处请见谅–

] 异步编制程序, 剖析异步方法 序
那是上篇《起始接触 async/await
异步编制程序》(入门)的第一章内容,首要是深深了然异步方法,提出咱们先…

 

倘诺您的法子有操作数为 TResult 类型的归来语句,则为
Task<TResult>。

 

若是您的秘技未有回去语句或具有未有操作数的归来语句,则为 Task。

 

1经你编写的是异步事件处理程序,则为 Void(Visual Basic 中为 Sub)。

 

有关详细音信,请参见本大旨后边的“重回类型和参数”。

 

艺术壹般包蕴至少1个 await
表明式,该表明式标志1个点,在该点上,直到等待的异步操作完结措施展本事能继续。
同时,将艺术挂起,并且控件再次来到到点子的调用方。(那里所谓的挂起就是上文所涉嫌的许诺,异步方法承诺会给调用方2个结出)

 

三、示例

  实施才是验证真理的极品路线。

 

 

using System;

using System.Diagnostics;

using System.Net.Http;

using System.Threading.Tasks;

 

namespace 异步递归

{

    class Program

    {

        static void Main(string[] args)

        {

            Stopwatch stopwatch = new Stopwatch();

            stopwatch.Start();

            ConsoleAsync1();

            stopwatch.Stop();

            Console.WriteLine(“同步方法用时:” +
stopwatch.ElapsedMilliseconds);

            stopwatch.Reset();

            stopwatch.Start();

            ConsoleAsync();

            stopwatch.Stop();

            Console.WriteLine(“异步方法用时:”+
stopwatch.ElapsedMilliseconds);

 

            Console.Read();

        }

 

        private static async void ConsoleAsync()

        {

            Console.WriteLine(“异步方法起头”);

            Console.WriteLine(“Result:” + await SumAsync(10));

            Console.WriteLine(“异步方法甘休”);

        }

        private static async Task<int> SumAsync(int part)

        {

            if ((part += 10) >= 100)

            {

                return 100;

            }

            HttpClient client = new HttpClient();

            Task<string> getStringTask =
client.GetStringAsync(“”);

            Console.WriteLine(DateTime.Now.Millisecond + ” 异步 ” +
(await getStringTask).Length);

            return await SumAsync(part);

        }

 

        private static void ConsoleAsync1()

        {

            Console.WriteLine(“同步方法起初”);

            Console.WriteLine(“Result:” + SumAsync1(10));

            Console.WriteLine(“同步方法甘休”);

        }

 

        private static int SumAsync1(int part)

        {

            if ((part += 10) >= 100)

            {

                return 100;

            }

            HttpClient client = new HttpClient();

            Task<string> getStringTask =
client.GetStringAsync(“”);

            Console.WriteLine(DateTime.Now.Millisecond + ” 同步 ” +
getStringTask.Result.Length);

            return SumAsync1(part);

        }

    }

}

 

  示例介绍:

 

    一、那么些例子中有三种实现格局:(一)利用异步编制程序的主意贯彻(二)利用普通同步格局达成

 

    二、同时这些事例中贯彻了递归,这一个能够毫无思考,博主只是想证雅培下在异步的事态下,递归是不是行得通而已,实验结果为有效。

 

    三、那段代码中的GetStringAsync()方法是获得远程界面内容用的,首要指标是延伸响应时间。

 

  在运用四线程编写端口扫描程序时,笔者本身深感同步和显明所无线程都进行完的时光是贰个相比较艰难的题目。有园友评论说今后曾经不手动创造thread对象了,而是直接运用Task异步情势,小编的互连网编制程序老师也讲到了异步编制程序的优越性。在就学了课本上的文化后,进行了一个计算分享给大家。从.NET四.5开始,用async和await关键字再增多Task.Run是二个尤其科学的异步编制程序模型。

1.await和async

  异步方式从本事上看正是运用委托来促成的,它的重要利润是在异步推行的进程中,用户依然能够操控UI分界面。使用Task类和平运动用Thread类有为数不少形似的地方,Task类也是透过调用方法去完成二个职分的实现,方法可是是命名方式或匿超方式,在奉行进程中可应用async和await来兑现异步施行。async是3个修饰符,它只可以用在措施依然事件处理程序的签署中。对于艺术可分为有重回值和无再次回到值三种情景,事件则唯有1种,如上边三条语句所示:

    private async Task<int> MethodAsync();//有再次来到值的异步方法

    private async Task MethodAsync();//无重返值的异步方法

    private async void btnOk_Click();//异步事件处理程序

  await是2个运算符,它意味着等待异步实行的结果。也足以明白为await运算符实际上是对艺术的再次回到值举行操作,也便是对Task<Result>进行操作,而不是对艺术本身实行操作。还有少数要留心,await是一定要放在异步方法的里边,借使未有放在里面包车型大巴话,VS会自动报错。以下是async和await使用的例子: 

    private async void button5_Click(object sender, EventArgs e)
    {
      Task a = Method1Async();
      //此处可继续实施其余代码
      await a;//等待职务a完毕
      Task<int> b = Method2Async();
      //此处可继续推行别的代码
      int c = await b;//等待职分b完毕,且能够得到职责b的重临值
    }

    Task Method1Async();
    async Task<int> Method2Async()
    {
      await Task.Delay(100);
      return 1;
    }

  await和一道编制程序最大的差异之处是:异步等待职务到位的时候,在不会继续推行前边的代码时,也不会潜移默化分界面包车型地铁操作。在.NET提供的类中,异步方法都以预订用Async作为后缀,那样能够很明白的知道这一个方法是异步方法可能一块方法。

贰. 成立义务

  创制职责约等于将职务与要实践的办法联系起来,编写任务实施的点羊时,那几个措施既能够是联合方法也得以是异步方法,还足以是匿超级模特式。推行异步方法时,必须用async和Task共同表示不曾再次来到值的职分,用async和Task<TResult>共同表示重返值为TResult的任务。以下是概念试行职分的格局。

    private async void button5_Click(object sender, EventArgs e)
    {

      //Task.Run方法表示使用暗许的职责调度程序在线程池中通过后台实行钦点的天职

      //要是不需求团结去调度措施,使用这几个情势最方便
      await Task.Run(()=>Method1Async());//施行同步方法
      int c = await
Task.Run(()=>Method二Async());//实行异步方法
      await Task.Run(async () => { c = 贰;
});//施行异步匿名方式
    }
    void Method1Async();
    async Task<int> Method2Async(){…}

  Task.Run方法常用的重载情势有以下肆种,其余它也是能够用new关键字显得制造职分,可是这种办法用的不多。

    Task Run(Func<Task> function);//试行不带再次来到值的天职

    Task<TResult>
Run<TResult>(Func<Task<TResult>>
function);//实践带重回值的任务

    Task<TResult> Run<TResult>(Func<Task<TResult>>
function, CancellationToken
cancellationToken);//实施过程中得以监听撤除通告

    Task Run(Func<Task> function, CancellationToken
cancellationToken);//实施进度中得以监听撤废文告

三. 甘休职务

  在试行任务时必定会并发须要截至职分的动静,那里的告壹段落告诉义务你要及早停下来不再进行了,而不是直接销毁任务实例。那里能够打个假诺,学生一齐出去吃饭了,学生与先生都在班群里面,突然班群里老师说要让同学们集聚,即使全数同学都见到那么些音信,然后学生们开端出发,那样就足以正确的成团。上边的例子有2个很关键的前提,那正是怀有同学都要观望那个音信,也正是学员是随时监听音信的。CancellationTokenSource类和CancellationToken结构用于落到实处102线程、线程池和Task职分的撤除操作,处理格局与地点的例子相似。制造的班群便是CancellationTokenSource对象,收到的布告就是CancellationToken对象。CancellationTokenSource用于创建裁撤布告,CancellationToken则用于传播应撤废操作的通知,当调用职务前,能够先创制撤销源对象CancellationTokenSource
cts=new CancellationTokenSource();,假若愿目的在于30秒后活动发出打消布告,能够流传参数CancellationTokenSource(提姆eSpan.FromSeconds(30));CancellationToken
ct=cts.Token;,后一句代码是获得撤销的通报。CancellationTokenSource还有三个Cancel方法,将那特性子设为true时,该方法会将富有加多了吊销标识的CancellationToken对象的IsCancellationRequested属性都安装为true,那样撤除通告就传递到了正在实施的职分。

  职责收到撤废通告后,可以接纳三种办法来终止操作。第2种格局是简约的从委托重临。那种达成方式接近于在调用职分的代码中一个bool值来代表撤消通告,义务收到后就径直重临了。当使用那种方法时义务状态的重回值为TaskStatus.RanToCompletion枚举值,它表示平常完结,而不是TaskStatus.Canceled枚举值。第三种办法是在代码里吸引OperationCanceledException格外,并将其传递到在其上呼吁了撤废的标识,选拔那种方法收回的任务会更动为用Canceled枚举值表示的情事。完结引发这些的首选办法是调用ct.ThrowIfCancellationRequestes();。以下是代码示例,写了1个winform程序,利用进程条来撤除任务。第二个图是未曾抓住那些时,程序退出for循环,试行后边的代码后回来了,第一张图是第三种方式,引发了十二分后直接跳转到catch语句块了。

亚洲必赢官网 82

亚洲必赢官网 83

亚洲必赢官网 84

     CancellationTokenSource cts;
        private async void button3_Click(object sender, EventArgs e)
        {
            progressBar1.Maximum = 100;
            progressBar1.Value = 0;
            cts = new CancellationTokenSource();
            var aa = MYThreadAsync("a", cts.Token);
            try
            {
                await aa;
                listBox1.Items.Add("await后面");
            }
            catch
            {
                if (aa.IsCanceled)
                    listBox1.Items.Add("a取消");
            }
        }

        private void button4_Click(object sender, EventArgs e)
        {
            cts.Cancel();
        }

        public async Task MYThreadAsync(string s, CancellationToken ct)
        {
            for (int i = 0; i < 50; i++)
            {
                if (ct.IsCancellationRequested)
                    break;          //点击关闭按钮,IsCancellationRequested就为true,就会退出for循环,这是第一种方式
                progressBar1.Value += 2;
                await Task.Delay(100);
                ct.ThrowIfCancellationRequested();//这是第二种方式,它会终止任务并且返回catch语句块里面
            }
            listBox1.Items.Add("任务" + s + "完成了");
        }

亚洲必赢官网 85

四. 赢得职务实践的事态

  在异步编制程序中,很分明任务试行的动静是一个要命重大的参数。在任务的生命周期里,可以由此Status属性来博取职分实践的景色,当任务完毕后还足以因而职务属性知道职分成功的场馆。可应用职务实例的Status属性获取职责施行的动静,职责执行的气象用TaskStatus枚举表示,以下是TaskStatus的枚举值:

Created:职分已经早先化,但尚无进入调度计划

WaitingForActivation:该任务已进入调度安顿,正在等待被调度程序激活

WaitingToRun:该职务已被调度程序激活,但尚未开头实行

Running:该职责正在运作,但一向不到位

RanToCompletion:该义务现已打响做到

Canceled:该职分由于被撤回而成就,引发这几个或调用方已向该义务的CancellationToken发出复信号

Faulted:该职责因为出现未经处理的不胜而成功

WaitingForChildrenToComplete:该任务自小编已到位,正等待附加的子职务到位

  职务完结境况有关的性质有IsCompleted、IsCanceled和IsFaulted等品质,从单词意思上看简单掌握它们的情致,当中要留心IsCompleted属性表示职责是不是做到,无论是平常结束依然因为裁撤或尤其而做到都为做到。

5. 职务执行的速度

  有时候大家期望让某个异步操作提供进程通报,以便在分界面中显得异步操作施行的进程,能够用Progress<T>类来获得任务施行的快慢。以下是行使格局里的Report方法将艺术内变量的值传回创制职分的风云代码里,从而创新进程条的值。

亚洲必赢官网 86

     CancellationTokenSource cts;
        private async void button3_Click(object sender, EventArgs e)
        {
            progressBar1.Maximum = 100;
            progressBar1.Value = 0;
            cts = new CancellationTokenSource();
            CancellationToken ct = cts.Token;
            var pp = new Progress<int>();
            pp.ProgressChanged += (s, n) => {
                progressBar1.Value = n;
            };
            var tt = Task.Run(()=>MYThreadAsync(pp,cts.Token,500),cts.Token);
            try
            {
                await tt;
                if (tt.Exception == null)
                    listBox1.Items.Add("任务完成");
            }
            catch (Exception ex)
            {
                listBox1.Items.Add("异常" + ex.Message);
            }
        }         
        private void button4_Click(object sender, EventArgs e)
        {
            cts.Cancel();
        }
        public  void MYThreadAsync(IProgress<int> progress, CancellationToken ct, int delay)
        {
            int p = 0;//进度
            while (p < 100 && ct.IsCancellationRequested == false)
            {
                p += 1;
                Thread.Sleep(delay);
                progress.Report(p);//这个方法将会触发ProgressChanged事件更新进度条
            }
        }

亚洲必赢官网 87

六. 定期达成职责

  无论是服务器依然客户端,都以有按期完毕某些职分的急需的。System.Timers.Timer类是3个不错的定期设置类,那一个类能够挑动风云,但它暗中同意是在线程池中引发轩然大波,而不是在脚下线程中迷惑风云。Timer类的常用属性有AutoReset和Interval属性,AutoReset是得到或设置八个bool值,该值为true表示每一遍间隔甘休时都抓住三次Elapsed事变,false表示仅在第1回间隔截止时引发3次该事件。Interval属性是赢得或设置三回Elapsed事件的间隔时间,该值必须高于零并小于Int.马克斯Value,暗中认可值为十0纳秒。Timer类还有多少个常用艺术那就是Start和Stop方法。

  还有多个System.Threading.Timer类,它也是在线程池中定期实践职务,它与前七个Timer类的区分是此类不应用事件模型,而是一向通过TimerCallback类型的寄托来完结的。该类的构造函数为:Timer(TimerCallback
callback,Object state,TimeSpan douTime,TimeSpan
period)。callback表示要进行的办法,state代表2个涵盖回调方法要运用的新闻的对象,dueTime是第1遍调用回调方法在此以前延迟的年华,period表示每一趟调用回调方法的流年间隔,-壹表示终止。那样创立对象后,第贰遍达到dueTime延时时间会自行调用二次callback委托,今后每隔period时间间隔调用3回。以下是那二种艺术的运作效果和源代码。亚洲必赢官网 88

 

亚洲必赢官网 89

     System.Timers.Timer timer;
        System.Threading.Timer threadtimer;
        private void button2_Click(object sender, EventArgs e)//Timers.Timer
        {
            progressBar1.Maximum = 100;
            progressBar1.Value = 0;
            int pro=0;
            timer = new System.Timers.Timer(500);
            timer.AutoReset = true;
            timer.Elapsed+= (obj, args) =>
            { 
                pro+=5;
                progressBar1.Value = pro;
            };
            timer.Start();
        }

       private void button5_Click(object sender, EventArgs e)
       {
           timer.Stop();
           listBox1.Items.Add("第一个已经停止");
       }
    //Threading.Timer类
       private void button1_Click(object sender, EventArgs e)
       {
           progressBar2.Maximum = 100;
           progressBar2.Value = 0;
           TimeSpan dueTime = new TimeSpan(0, 0, 0, 1);
           TimeSpan period = new TimeSpan(0, 0, 0, 0, 200);
           System.Threading.TimerCallback timecall = new TimerCallback((obj) => progressBar2.Value += 5);
           threadtimer = new System.Threading.Timer(timecall, null, dueTime, period);
       }

       private void button6_Click(object sender, EventArgs e)
       {
           threadtimer.Dispose();
           listBox1.Items.Add("第二个已经停止");
       }

亚洲必赢官网 90

  那篇作品只总括了单个职分的异步试行的根基,还得继续上学多任务并行实践。如若有更加好的本事依旧与商家运用相关的异步技艺,希望园友能够提议本人继续学习。

网站地图xml地图