导航

async方法:async+await

Posted on 2017-08-22 21:19  清浅ヾ  阅读(188)  评论(0编辑  收藏  举报
 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading;
 6 using System.Threading.Tasks;
 7 
 8 namespace 异步
 9 {
10     class AwaitAsyncShow
11     {
12 
13 
14         #region 没有await前提下与普通方法无异
15         /// <summary>
16         /// 注:async与await要成对出现,否则生命async方法无效
17         /// async与await只能在方法中声明,如下
18         /// </summary>
19         public static async void Show()  //这里有警告正常
20         {
21             Console.WriteLine("开始执行前...");
22             Task task = Task.Run(() =>
23             {
24                 Console.WriteLine("这里是异步多线程开始调用......");
25             });
26             //如果在task后面不加await,则只能当成普通方法使用,且不会有线程等待
27             Console.WriteLine("开始执行后...");
28         }
29         #endregion
30 
31         #region 异步方法await+async
32         public static void Invoke()
33         {
34             AwaitShow();// 这里执行异步方法
35             //在上面的AwaitShow()用await task等待的时候,这里主线程开始执行下面的任务
36             for (int i = 0; i < 8; i++)
37             {
38                 Console.WriteLine($"这里由主线程来执行,当前线程ID为:{Thread.CurrentThread.ManagedThreadId}......");
39             }
40         }
41 
42         public static async void AwaitShow()
43         {
44             Console.WriteLine($"开始执行前,当前线程id:{Thread.CurrentThread.ManagedThreadId}...");
45             Task task = Task.Run(() =>
46             {
47                 Console.WriteLine($"这里是异步多线程开始调用1,当前线程ID为:{Thread.CurrentThread.ManagedThreadId}......");
48                 Thread.Sleep(2000);
49                 Console.WriteLine($"这里是异步多线程开始调用2,当前线程ID为:{Thread.CurrentThread.ManagedThreadId}......");
50             });
51             await task; //主线程到这里就返回到上面的Invoke()方法中,去执行别的任务去了
52 
53             //后面的这句话当成了一个委托,task的回调函数了,等到task子线程执行完后执行这句话
54             //这个回调线程是不确定的,可以是主线程,也可以是子线程
55             Console.WriteLine($"开始执行后,当前线程id:{Thread.CurrentThread.ManagedThreadId}...");
56         }
57         #endregion
58 
59 
60         #region 带返回值得async异步方法,没有return语句,反人类
61         public static async Task NoReturnTask()
62         {
63             Console.WriteLine($"开始执行前,当前线程id:{Thread.CurrentThread.ManagedThreadId}...");
64             Task task= Task.Run(() =>
65             {
66                 Console.WriteLine($"这里是异步多线程开始调用1,当前线程ID为:{Thread.CurrentThread.ManagedThreadId}......");
67                 Thread.Sleep(2000);
68                 Console.WriteLine($"这里是异步多线程开始调用2,当前线程ID为:{Thread.CurrentThread.ManagedThreadId}......");
69             });
70             await task;  //在这里直接返回task,吊不吊 
71 
72             //注:这里相当没有返回值,最好不要用void类型,可用Task类型
73         }
74         #endregion
75 
76         #region 更反人类的返回类型
77         public static async Task<long> SumAsync()
78         {
79             Console.WriteLine($"开始执行前,当前线程id:{Thread.CurrentThread.ManagedThreadId}...");
80             long sum = 0;
81             await Task.Run(() => 
82             {
83                 for (int i = 0; i < 10000000; i++)
84                 {
85                     sum += i;
86                 }
87             });
88             Console.WriteLine($"开始执行后,当前线程id:{Thread.CurrentThread.ManagedThreadId}...");
89             return sum;  //返回类型明明是Task<long>类型,但返回值却是long类型,就像返回一个委托一样
90 
91             //如果要返回一个类型值,请用Task<T> 相当于委托
92         }
93         #endregion
94     }
95 }

 

主程序调用

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading.Tasks;
 6 
 7 namespace 异步
 8 {
 9     class Program
10     {
11         static void Main(string[] args)
12         {
13             AwaitAsyncShow.Invoke();
14 
15             //这里调用带返回值的async方法
16             Task<long> sumTask = AwaitAsyncShow.SumAsync();
17             long result = sumTask.Result;
18             Console.WriteLine($"sum结果为:{result}");
19             Console.ReadLine();
20         }
21     }
22 }

 执行结果