自从 C# 5.0 时代引入 async 和 await 关键字后, 异步编程就变得流行起来. 尤其在现在的. NET Core 时代, 如果你的代码中没有出现 async 或者 await 关键字, 都会让人感觉到很奇怪.
想象一下当我们在处理 UI 和按钮单击时, 我们需要运行一个长时间运行的方法, 比如读取一个大文件或其他需要很长时间的任务, 在这种情况下, 整个应用程序必须等待这个长时间运行的任务完成才算完成整个任务.
换句话说, 如果同步应用程序中的任何进程被阻塞, 则整个应用程序将被阻塞, 我们的应用程序将停止响应, 直到整个任务完成.
在这种情况下, 异步编程将非常有用. 通过使用异步编程, 应用程序可以继续进行不依赖于整个任务完成的其他工作.
在 Async 和 await 关键字的帮助下, 使得异步编程变得很简单, 而且我们将获得传统异步编程的所有好处.
实例讲解
假设我们分别使用了两种方法, 即 Method 1 和 Method 2, 这两种方法不相互依赖, 而 Method 1 需要很长时间才能完成它的任务. 在同步编程中, 它将执行第一个 Method 1, 并等待该方法的完成, 然后执行 Method 2. 因此, 这将是一个时间密集型的过程, 即使这两种方法并不相互依赖.
我们可以使用简单的多线程编程并行运行所有方法, 但是它会阻塞 UI 并等待完成所有任务. 要解决这个问题, 我们必须在传统编程中编写很多的代码, 但是现在我们有了 Async 和 await 关键字, 那么我们将通过书写很少的并且简洁的代码来解决这个问题.
此外, 我们还将看到更多的示例, 如果任何第三个方法 (如 Method 3) 都依赖于 Method 1, 那么它将在 Wait 关键字的帮助下等待 Method 1 的完成.
Async 和 await 是代码标记, 它标记代码位置为任务完成后控件应该恢复的位置.
下面让我们举几个例子来更好进行理解吧
C# 中 Async 和 await 关键字的示例
我们将采用控制台应用程序进行演示.
第一个例子
在这个例子中, 我们将采取两个不相互依赖的方法.
- class Program
- {
- static void Main(string[] args)
- {
- Method1();
- Method2();
- Console.ReadKey();
- }
- public static async Task Method1()
- {
- await Task.Run(() =>
- {
- for (int i = 0; i <100; i++)
- {
- Console.WriteLine("Method 1");
- }
- });
- }
- public static void Method2()
- {
- for (int i = 0; i < 25; i++)
- {
- Console.WriteLine("Method 2");
- }
- }
- }
在上面给出的代码中, Method 1 和 Method 2 不相互依赖, 我们是从主方法调用的.
在这里, 我们可以清楚地看到, 方法 1 和方法 2 并不是在等待对方完成.
输出
现在来看第二个例子, 假设我们有 Method 3, 它依赖于 Method 1
第二个例子
在本例中, Method 1 将总长度作为整数值返回, 我们在 Method 3 中以长度的形式传递一个参数, 它来自 Method 1.
在这里, 在传递 Method 3 中的参数之前, 我们必须使用 AWAIT 关键字, 为此, 我们必须使用调用方法中的 async 关键字.
在控制台应用程序的 Main 方法中, 因为不能使用 async 关键字而不能使用 await 关键字, 因为它会给出下面给出的错误.(但是如果你使用的是 C#7.1 及以上的方法是不会有问题的, 因为 C#7.1 及以上的语法支持 Mian 方法前加 async)
我们将创建一个新的方法, 作为 CallMethod, 在这个方法中, 我们将调用我们的所有方法, 分别为 Method 1,Method 2 和 Method 3.
- class Program
- {
- static void Main(string[] args)
- {
- callMethod();
- Console.ReadKey();
- }
- public static async void callMethod()
- {
- Task<int> task = Method1();
- Method2();
- int count = await task;
- Method3(count);
- }
- public static async Task<int> Method1()
- {
- int count = 0;
- await Task.Run(() =>
- {
- for (int i = 0; i <100; i++)
- {
- Console.WriteLine("Method 1");
- count += 1;
- }
- });
- return count;
- }
- public static void Method2()
- {
- for (int i = 0; i < 25; i++)
- {
- Console.WriteLine("Method 2");
- }
- }
- public static void Method3(int count)
- {
- Console.WriteLine("Total count is" + count);
- }
- }
在上面给出的代码中, Method 3 需要一个参数, 即 Method 1 的返回类型. 在这里, await 关键字对于等待 Method 1 任务的完成起着至关重要的作用.
输出
第三个例子
.NET Framework4.5 中有一些支持 API,Windows 运行时包含支持异步编程的方法.
在 Async 和 await 关键字的帮助下, 我们可以在实时项目中使用所有这些, 以便更快地执行任务.
包含异步方法的 API 有 HttpClient, SyndicationClient, StorageFile, StreamWriter, StreamReader, XmlReader, MediaCapture, BitmapEncoder, BitmapDecoder 等.
在本例中, 我们将异步读取大型文本文件中的所有字符, 并获取所有字符的总长度.
- class Program
- {
- static void Main()
- {
- Task task = new Task(CallMethod);
- task.Start();
- task.Wait();
- Console.ReadLine();
- }
- static async void CallMethod()
- {
- string filePath = "E:\\sampleFile.txt";
- Task<int> task = ReadFile(filePath);
- Console.WriteLine("Other Work 1");
- Console.WriteLine("Other Work 2");
- Console.WriteLine("Other Work 3");
- int length = await task;
- Console.WriteLine("Total length:" + length);
- Console.WriteLine("After work 1");
- Console.WriteLine("After work 2");
- }
- static async Task<int> ReadFile(string file)
- {
- int length = 0;
- Console.WriteLine("File reading is stating");
- using (StreamReader reader = new StreamReader(file))
- {
- // Reads all characters from the current position to the end of the stream asynchronously
- // and returns them as one string.
- string s = await reader.ReadToEndAsync();
- length = s.Length;
- }
- Console.WriteLine("File reading is completed");
- return length;
- }
- }
在上面给出的代码中, 我们调用 ReadFile 方法来读取文本文件的内容, 并获取文本文件中总字符的长度.
在 sampleText.txt 中, 文件包含了太多的字符, 因此读取所有字符需要很长时间.
在这里, 我们使用异步编程从文件中读取所有内容, 所以它不会等待从这个方法获得一个返回值并执行其他代码行, 但是它必须等待下面给出的代码行, 因为我们使用的是等待关键字, 我们将对下面给出的代码行使用返回值.
- int length = await task;
- Console.WriteLine("Total length:" + length);
随后, 将按顺序执行其他代码行.
- Console.WriteLine("After work 1");
- Console.WriteLine("After work 2");
输出
来源: http://www.bubuko.com/infodetail-3109718.html