【C#】异步的用法

拈花ヽ惹草 提交于 2021-02-04 02:39:23

1. C#5.0 加入了async, await关键字. async是在声明异步方法时使用的修饰符, 声明放在返回值之前即可,await表达式则负责消费异步操作, 不能出现在catch或finally块, 非异步匿名函数(没有用async声明的匿名方法或者lambda表达式), lock语句或不安全的代码中使用。

ps:这些约束条件是为了保证安全,特别是关于锁的约束。如果你希望在异步操作完成时持有锁,那么应该重新设计你的代码。不要通过在try/finally块中手动调用Monitor.TryEnterMonitor.Exit的方式绕过编译器的限制,而应该实现代码的更改,这样在操作过程中就不再需要锁了。如果此时的情况不允许代码的改变,则可考虑使用SemaphoreSlim和它的WaitAsync方法来代替。

2. 所有用async修饰的异步方法, 参数都不可以使用out 或者 ref 修饰符. 返回值必须是void, task, task<T>. 一般为task. 因为可以让调用者监控异步操作的状态.

3. await的主要目的是在等待耗时操作完成时避免阻塞。代码总是在执行到await的时候就开始返回了, 并且到达await之后会校验结果是否存在 如果结果不存在, 会安排给一个后续操作, 这个后续操作会记录位置,状态, 然后代码回到UI主线程继续运行, 此时button.click方法实际上已经执行结束. 现在的调用栈就是windows form的事件循环, 当await标记的结果得到时会继续运行之后的代码.

下面是我写的一个demo小测试程序:

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading.Tasks;
 6 using System.Threading;
 7 using System.Net.Http;
 8 using System.Net;
 9 using System.Diagnostics;
10 using System.IO;
11 
12 namespace DennisDemos.Demos
13 {
14     class AsyncDemo
15     {
16         public void Run()
17         {
18             //var result = Test1();
19             //Console.WriteLine(result.Result);// 必须等到结果之后才能继续执行下面的代码. 所以result是同步的.
20             //Console.WriteLine("test1 end");
21             Console.WriteLine("MainAsync start.");
22             var result2 = MainAsync();
23             
24             Console.WriteLine("MainAsync end.");
25             while (!result2.IsCompleted)
26             {
27                 Thread.Sleep(1000);
28                 Console.WriteLine("waiting..");
29             }
30             Console.WriteLine("end.");
31         }
32         static async Task MainAsync()
33         {
34             Task<string> task = ReadFileAsync("LogicDocument_DocAveLoadBalance.docx");   //❶ 开始异步读取
35             try
36             {
37                 Console.WriteLine("start to wait reads file reult.");
38                 string text = await task;     //❷ 等待内容
39                 Thread.Sleep(10000);
40                 Console.WriteLine("File contents");
41             }
42             catch (IOException e)    //❸ 处理IO失败
43             {
44                 Console.WriteLine("Caught IOException: {0}", e.Message);
45             }
46         }
47 
48         static async Task<string> ReadFileAsync(string filename)
49         {
50             Console.WriteLine("start to read file async.");
51             using (var reader = File.OpenText(filename))    //❹ 同步打开文件
52             {
53                 var result = await reader.ReadToEndAsync();
54                 Thread.Sleep(1000);
55                 Console.WriteLine("get read file async result.");
56                 return result;
57             }
58         }
59     }
60 }
AsyncDemo

 

to be continued..

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!