当前位置: 首页 > news >正文

Async和Await关键字

文章目录

  • 前言
  • 一、基本概念
  • 二、使用步骤


前言

Async和Await关键字!


一、基本概念

async 关键字
基本概念 :async 修饰符用于指定方法是异步执行的,它告诉编译器该方法中可能包含一个或多个 await 表达式。被 async 修饰的方法称为异步方法,它会返回一个任务对象(Task 或 Task<TResult>),该任务对象表示异步操作。
语法 :在方法声明中使用 async 修饰符,位于访问修饰符之后,返回类型之前。例如:
async Task MyAsyncMethod()
async Task<int> MyAsyncMethod()
await 关键字
基本概念 :await 运算符用于等待异步操作完成。它会暂停当前方法的执行,直到等待的异步操作完成,然后将控制权交回给调用者。await 操作符通常用于等待 Task 或 Task<TResult> 对象。
语法 :在表达式前面使用 await 关键字,通常用于等待异步方法返回的 Task 或 Task。例如:
await MyAsyncMethod();
int result = await MyAsyncMethod();

二、使用步骤

首看一下效果
同步效果,当执行比较耗时的IO时,主线程会被阻塞在比较耗时的IO处,得等到IO结束才能执行后面的代码,所以当还在下载内容时,窗体拖不动,得等到IO结束后才能拖动。

private void btnSyncDownload_Click(object sender, EventArgs e)
{txtResult.Text = "";var stopwatch = Stopwatch.StartNew();DownloadWebSietSycn();txtResult.Text += $"Elapsed time: {stopwatch.Elapsed}{Environment.NewLine}";
}private void DownloadWebSietSycn()
{foreach (var site in Contents.WebSites){var result = DownloadWebSitSync(site);ReportResult(result);}
}private void ReportResult(string result)
{txtResult.Text += result;
}private string DownloadWebSitSync(string url)
{var response = client.GetAsync(url).GetAwaiter().GetResult();var responsePayloadBytes = response.Content.ReadAsByteArrayAsync().GetAwaiter().GetResult();return $"Finish downloding data from {url}. Total bytes returned {responsePayloadBytes.Length}. {Environment.NewLine}";
}

在这里插入图片描述

使用Async和Await关键字就是告诉主线程,这个任务是交给其他线程处理,你可以继续去执行其他任务。代码解析:var result = await Task.Run(() => DownloadWebSitSync(site));表示需要等待这个线程执行完成并使用result 来接收返回值。

private async Task btnAsyncDownload_Click(object sender, EventArgs e)
{txtResult.Text = "";var stopwatch = Stopwatch.StartNew();DownloadWebSietAsycn();txtResult.Text += $"Elapsed time: {stopwatch.Elapsed}{Environment.NewLine}";
}private async Task DownloadWebSietAsycn()
{foreach (var site in Contents.WebSites){var result = await Task.Run(() => DownloadWebSitSync(site));ReportResult(result);}
}

注意:对于async 和await方法的返回值必须得是Task或者Task
在这里插入图片描述

仔细看,这个耗时在第一行就打印出来了并且用时非常短。
在这里插入图片描述
为了能在执行完DownloadWebSietAsycn()后执行这段txtResult.Text += $“Elapsed time: {stopwatch.Elapsed}{Environment.NewLine}”;代码,可以加上await关键字。

private async Task btnAsyncDownload_Click(object sender, EventArgs e)
{txtResult.Text = "";var stopwatch = Stopwatch.StartNew();await DownloadWebSietAsycn();txtResult.Text += $"Elapsed time: {stopwatch.Elapsed}{Environment.NewLine}";
}private async Task DownloadWebSietAsycn()
{foreach (var site in Contents.WebSites){var result = await Task.Run(() => DownloadWebSitSync(site));ReportResult(result);}
}

效果图
在这里插入图片描述

可以看出加了await关键字后这段代码txtResult.Text += $“Elapsed time: {stopwatch.Elapsed}{Environment.NewLine}”;会等DownloadWebSietAsycn()执行完才执行。
在这里插入图片描述
第一段代码

private async Task btnAsyncDownload_Click(object sender, EventArgs e)
{txtResult.Text = "";var stopwatch = Stopwatch.StartNew();DownloadWebSietAsycn();txtResult.Text += $"Elapsed time: {stopwatch.Elapsed}{Environment.NewLine}";
}

未使用 await 等待异步操作 :当调用 DownloadWebSietAsycn() 时,程序不会等待它完成,而是直接继续执行后续代码。
可能导致操作顺序问题 :这意味着在 DownloadWebSietAsycn 方法完成之前,可能会执行 txtResult.Text += … 这一行代码。这可能导致以下问题:
显示不完整的异步操作结果 :如果 DownloadWebSietAsycn 方法的任务还未完成,那么在这行代码执行时,txtResult 中可能不会显示完整的异步操作结果。
显示较长的经过时间 :即使 DownloadWebSietAsycn 方法的时间非常短,但由于 txtResult.Text += … 这行代码会立即执行,显示的经过时间可能会比实际时间长,因为它没有等待异步操作完成。
第二段代码

private async Task btnAsyncDownload_Click(object sender, EventArgs e)
{txtResult.Text = "";var stopwatch = Stopwatch.StartNew();await DownloadWebSietAsycn();txtResult.Text += $"Elapsed time: {stopwatch.Elapsed}{Environment.NewLine}";
}

使用 await 等待异步操作 :当调用 await DownloadWebSietAsycn() 时,程序会暂停当前方法的执行,等待 DownloadWebSietAsycn 方法完成后再继续执行后续代码。
确保操作顺序 :这意味着在 DownloadWebSietAsycn 方法完成之前,不会执行 txtResult.Text += … 这一行代码。因此,你可以确保在 DownloadWebSietAsycn 方法完成后,才去获取和显示经过时间。
性能和响应能力 :在等待 DownloadWebSietAsycn 方法完成时,线程不会被阻塞,这样可以提高程序的性能和响应能力,改善用户体验。

在 await DownloadWebSietAsycn() 中,程序的其他任务不会等待 DownloadWebSietAsycn() 执行完成 ,只有当前的异步方法(这里是 btnAsyncDownload_Click)会在这个 await 表达式处暂停执行,等待 DownloadWebSietAsycn() 完成。
当前异步方法的暂停
在遇到 await DownloadWebSietAsycn() 时,btnAsyncDownload_Click 方法会把控制权交还给调用者(通常是 UI 消息循环)。它会在 DownloadWebSietAsycn() 返回的结果(因为 DownloadWebSietAsycn() 是异步方法,返回的是一个 Task)完成后,继续执行后续代码。
这是异步编程的一个关键特性,它允许方法在等待异步操作完成时,不阻塞整个线程。这样可以使应用程序的 UI 保持响应,因为 UI 线程没有被长时间占用。
其他任务的执行
如果程序中有其他独立的任务,它们不会因为 DownloadWebSietAsycn() 的执行而被阻塞。例如,如果有其他按钮点击事件处理程序或者其他后台线程任务,它们可以继续执行。
这是因为现代操作系统和编程环境(如 C# 的多线程和异步编程模型)允许多个任务并行运行。在 C# 中,异步方法通常是基于任务(Task - based)的异步模式,这些任务可以在后台线程池中执行,或者以其他非阻塞的方式运行。

http://www.lqws.cn/news/597367.html

相关文章:

  • 电力交易的实现路径
  • CppCon 2018 学习:A New Take on Polymorphism
  • (JAVA)自建应用调用企业微信API接口,实现消息推送
  • 【网工|知识升华版|理论】ARQ机制|CSMA/CD协议
  • Rust征服字节跳动:高并发服务器实战
  • 记一次使用sa-token导致的预检请求跨域问题
  • 前端常用构建工具介绍及对比
  • 人才交流的价值创造模型与合作演化方程
  • Kubernetes Pod 调度基础
  • 华为设备 QoS 流分类与流标记深度解析及实验脚本
  • 【UniApp picker-view 多列对齐问题深度剖析与完美解决】
  • 4.Stable Diffusion WebUI 模型训练
  • OpenCV CUDA模块设备层-----“大于阈值设为零” 的图像处理函数 thresh_to_zero_inv_func()
  • torch.nn
  • Postman - API 调试与开发工具 - 标准使用流程
  • Mac 部署 Dify小红书种草工作流
  • 新手向:从零开始MySQL超详细安装、配置与使用指南
  • stm32l4系列启用看门狗后,调用HAL_IWDG_Refreh()就复位
  • HakcMyVM-Arroutada
  • java生成word文档
  • 飞算JavaAI:重构软件开发范式的智能引擎
  • ABB驱动系列SCYC51213 63911607C驱动板
  • java微服务-linux单机CPU接近100%优化
  • Python应用指南:利用高德地图API获取公交+地铁可达圈(二)
  • 再见 RAG?Gemini 2.0 Flash 刚刚 “杀死” 了它!
  • 学习面向对象
  • 第TR3周:Pytorch复现Transformer
  • 快速手搓一个MCP服务指南(九): FastMCP 服务器组合技术:构建模块化AI应用的终极方案
  • 【仿muduo库实现并发服务器】Poller模块
  • 基于中国印尼会计准则差异,中国企业在印尼推广ERP(SAP、Oracle)系统需要注意的细节