当前位置: 首页> 文旅> 旅游 > 建筑企业信用分查询系统_wap手机网站开发_缅甸新闻最新消息_广告推广app

建筑企业信用分查询系统_wap手机网站开发_缅甸新闻最新消息_广告推广app

时间:2025/7/14 16:19:03来源:https://blog.csdn.net/mss359681091/article/details/144423926 浏览次数:1次
建筑企业信用分查询系统_wap手机网站开发_缅甸新闻最新消息_广告推广app

文章目录

  • 一、引言 📖
  • 二、异步编程的基本概念
  • 三、Async 和 Await 的基本用法
  • 四、Async 方法的转换过程
  • 五、Await 的工作原理
  • 六、异步方法的执行流程
  • 七、异常处理
  • 八、避免常见陷阱
    • 8.1 死锁
    • 8.2 忘记await
    • 8.3 过度使用 async void
  • 九、高级模式
    • 9.1 并行执行多个任务
    • 9.2 带超时的异步操作
  • 十、结论
  • 十一、代码之美系列目录🎀🎀🎀


一、引言 📖

💎在C#中, asyncawait 关键字是用于实现异步编程的强大工具。它们的引入极大地 简化异步 代码的编写,使得开发人员能够更容易地创建响应式和高性能的应用程序。但是,要真正理解它们的工作原理,我们需要深入探讨它们在底层到底在做什么。

二、异步编程的基本概念

在深入asyncawait 之前,我们需要理解一些基本概念:

  • 同步执行: 代码按顺序执行,每个操作完成后才会进行下一个。
  • 异步执行:允许长时间运行的操作在后台进行,而不阻塞主线程。
  • 任务(Task): 表示一个异步操作。
  • 线程: 程序执行的最小单位。

三、Async 和 Await 的基本用法

让我们从一个简单的例子开始:

static async Task Main(string[] args)
{var context = await GetWebContentAsync("http://www.baidu.com");Console.WriteLine(context);
}public static async Task<string> GetWebContentAsync(string url)
{using (var client = new HttpClient()){string content = await client.GetStringAsync(url);return content;}
}

在这个例子中:

  • async关键字标记方法为异步方法。
  • 方法返回 Task ,表示一个最终会产生 string 的异步操作。
  • await 用于等待 GetStringAsync 方法完成,而不阻塞线程。

四、Async 方法的转换过程

当你使用 async 关键字标记一个方法时,编译器会将其转换为一个 状态机 。这个过程大致如下:

  1. 创建一个实现了 IAsyncStateMachine 接口的结构体。
  2. 将方法体转换为状态机的 MoveNext 方法。
  3. 每个 await 表达式都成为一个可能 的暂停点 ,对应状态机中的一个状态。

async 方法如何被分解为多个步骤,每个 await 表达式对应一个状态。

五、Await 的工作原理

await 关键字的主要作用是:

  • 检查 awaited 任务是否已完成。
  • 如果已完成,继续执行后续代码。
  • 如果未完成,注册一个回调并返回控制权给调用者。

让我们通过一个例子来详细说明:

public async Task DoWorkAsync()
{Console.WriteLine("开始工作");await Task.Delay(1000); // 模拟耗时操作Console.WriteLine("工作完成");
}

当执行到 await Task.Delay(1000) 时:

  1. 检查 Task.Delay(1000) 是否已完成。
  2. 如果未完成:
    • 创建一个 continuation (后续操作),包含 await 之后的代码。
    • 将这个 continuation 注册到Task上。
    • 返回控制权给调用者。
  3. Task.Delay(1000) 完成时:
    • 触发注册的 continuation
    • 恢复执行 await 之后的代码。

六、异步方法的执行流程

让我们通过一个更复杂的例子来理解 异步方法 的执行流程:

static async Task Main(string[] args)
{await MainMethodAsync();Console.ReadKey();
}public static async Task MainMethodAsync()
{Console.WriteLine("1. 开始主方法");await Method1Async();Console.WriteLine("4. 主方法结束");
}public static async Task Method1Async()
{Console.WriteLine("2. 开始方法1");await Task.Delay(1000);Console.WriteLine("3. 方法1结束");
}

在这里插入图片描述
执行流程如下:

  1. MainMethodAsync 开始执行,打印"1. 开始主方法"。
  2. 遇到 await Method1Async(),进入Method1Async
  3. Method1Async 打印"2. 开始方法1"。
  4. 遇到 await Task.Delay(1000) ,注册 continuation 并返回。
  5. 控制权回到 MainMethodAsync,但因为 Method1Async 未完成,所以 MainMethodAsync 也返回。
  6. 1秒后 ,Task.Delay 完成,触发 continuation
  7. Method1Async 继续执行,打印"3. 方法1结束"。
  8. Method1Async 完成,触发 MainMethodAsynccontinuation
  9. MainMethodAsync 继续执行,打印"4. 主方法结束"。

七、异常处理

async/await 模式下的异常处理非常直观。你可以使用常规的 try/catch 块,异步方法中抛出的异常会被封装在返回的 Task 中,并在 await 时重新抛出。

八、避免常见陷阱

使用 async/await 时,有一些常见的陷阱需要注意:

8.1 死锁

考虑如下代码:

public async Task DeadlockDemoAsync()
{await Task.Delay(1000).ConfigureAwait(false);
}public void CallAsyncMethod()
{DeadlockDemoAsync().Wait(); // 可能导致死锁
}
  • 当在 UI线程(或任何有同步上下文的线程)中调用 CallAsyncMethod() 时,会发生死锁。
  • Wait() 方法会阻塞当前线程,等待异步操作完成。
  • 当异步操作完成时,它默认会尝试在原始的同步上下文(通常是UI线程)上继续执行。
  • 但是原始线程已经被 Wait() 阻塞了,导致死锁。

8.2 忘记await

public async Task ForgetAwaitDemoAsync()
{DoSomethingAsync(); // 忘记awaitConsole.WriteLine("完成"); // 这行可能在异步操作完成之前执行
}

8.3 过度使用 async void

除了事件处理程序外,应避免使用 async void 方法,因为它们的异常难以捕获和处理。

public async void BadAsyncVoidMethod()
{await Task.Delay(1000);throw new Exception("这个异常很难被捕获");
}

九、高级模式

9.1 并行执行多个任务

使用 Task.WhenAll 可以并行执行多个异步任务:

public async Task ParallelExecutionDemo()
{var task1 = DoWorkAsync(1);var task2 = DoWorkAsync(2);var task3 = DoWorkAsync(3);await Task.WhenAll(task1, task2, task3);Console.WriteLine("所有任务完成");
}public async Task DoWorkAsync(int id)
{await Task.Delay(1000);Console.WriteLine($"任务 {id} 完成");
}

在这里插入图片描述

9.2 带超时的异步操作

使用 Task.WhenAnyTask.Delay 可以实现带超时的异步操作:

static async Task Main(string[] args)
{await FetchDataWithTimeoutAsync("http://www.google.com",new TimeSpan(0, 0, 3));Console.ReadKey();
}static async Task<string> FetchDataWithTimeoutAsync(string url, TimeSpan timeout)
{using (var client = new HttpClient()){var dataTask = client.GetStringAsync(url);var timeoutTask = Task.Delay(timeout);var completedTask = await Task.WhenAny(dataTask, timeoutTask);if (completedTask == timeoutTask){throw new TimeoutException("操作超时");}return await dataTask;}
}

十、结论

asyncawait 极大地简化了 C# 中的异步编程,使得编写高效、响应式的应用程序变得更加容易。通过将复杂的 异步操作 转换为看似 同步 的代码,它们提高了代码的 可读性可维护性

十一、代码之美系列目录🎀🎀🎀

一、C# 命名规则规范
二、C# 代码约定规范
三、C# 参数类型约束
四、浅析 B/S 应用程序体系结构原则
五、浅析 C# Async 和 Await
六、浅析 ASP.NET Core SignalR 双工通信
七、浅析 ASP.NET Core 和 MongoDB 创建 Web API
八、浅析 ASP.NET Web UI 框架 Razor Pages/MVC/Web API/Blazor
九、如何使用 MiniProfiler WebAPI 分析工具
十、浅析 .NET Core 中各种 Filter
十一、C#.Net筑基-类型系统
十二、C#.Net 筑基-运算符
十三、C#.Net筑基-解密委托与事件
十四、C#.Net筑基-集合知识大全
十五、C#.Net筑基 - 常见类型
十六、C#.NET体系图文概述—2024最全总结

在这里插入图片描述

关键字:建筑企业信用分查询系统_wap手机网站开发_缅甸新闻最新消息_广告推广app

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: