C# 中的Task

文章目录

  • 前言
  • 一、Task 的基本概念
  • 二、创建 Task
    • 使用异步方法
    • 使用 Task.Run 方法
  • 三、等待 Task 完成
    • 使用 await 关键字
    • 使用 Task.Wait 方法
  • 四、处理 Task 的异常
    • 使用 try-catch 块
    • 使用 Task.Exception 属性
  • 五、Task 的延续
    • 使用 ContinueWith 方法
    • 使用 await 关键字和异步方法
  • 六、Task 的并行执行
    • 使用多个 Task
    • 使用 Task.WhenAll 方法
  • 七、总结


前言

  在 C# 中,Task代表一个异步操作。它允许你在不阻塞主线程的情况下执行耗时的操作,从而提高应用程序的响应性和性能。本教程将详细介绍 C# 中的Task。
在这里插入图片描述

一、Task 的基本概念

  Task是.NET Framework 4.0 引入的一种异步编程模型,它代表一个可能尚未完成的操作。Task可以表示任何异步操作,例如文件读取、网络请求、数据库查询等。与传统的异步编程模型相比,Task提供了一种更加简洁和高效的方式来处理异步操作。

二、创建 Task

使用异步方法

  C# 中的异步方法通常以async关键字开头,并返回一个Task或Task。例如:

   async Task<int> CalculateSumAsync()
   {
       int sum = 0;
       for (int i = 0; i < 100; i++)
       {
           sum += i;
       }
       return sum;
   }

  在这个例子中,CalculateSumAsync方法是一个异步方法,它返回一个Task,表示一个异步操作,该操作将计算从 0 到 99 的整数之和,并返回结果。

使用 Task.Run 方法

  Task.Run方法可以将一个委托作为参数,并在一个新的线程上执行该委托。例如:

   Task<int> task = Task.Run(() =>
   {
       int sum = 0;
       for (int i = 0; i < 100; i++)
       {
           sum += i;
       }
       return sum;
   });

  在这个例子中,Task.Run方法将一个 lambda 表达式作为参数,该表达式计算从 0 到 99 的整数之和,并返回结果。Task.Run方法返回一个Task,表示在新线程上执行的异步操作。

三、等待 Task 完成

使用 await 关键字

  await关键字用于等待一个Task完成。当使用await关键字等待一个Task时,当前方法会暂停执行,直到Task完成。例如:

   async Task<int> CalculateSumAsync()
   {
       int sum = 0;
       for (int i = 0; i < 100; i++)
       {
           sum += i;
       }
       return sum;
   }

   async Task Main()
   {
       int result = await CalculateSumAsync();
       Console.WriteLine(result);
   }

  在这个例子中,Main方法是一个异步方法,它调用CalculateSumAsync方法,并使用await关键字等待该方法完成。一旦CalculateSumAsync方法完成,result变量将被赋值为该方法的返回值,并在控制台上输出结果。

使用 Task.Wait 方法

  Task.Wait方法用于等待一个Task完成。与await关键字不同,Task.Wait方法会阻塞当前线程,直到Task完成。例如:

   Task<int> task = Task.Run(() =>
   {
       int sum = 0;
       for (int i = 0; i < 100; i++)
       {
           sum += i;
       }
       return sum;
   });

   task.Wait();
   int result = task.Result;
   Console.WriteLine(result);

  在这个例子中,task.Wait()方法会阻塞当前线程,直到task完成。一旦task完成,result变量将被赋值为task的返回值,并在控制台上输出结果。

四、处理 Task 的异常

使用 try-catch 块

  当等待一个Task时,可以使用try-catch块来捕获Task中发生的异常。例如:

   async Task<int> CalculateSumAsync()
   {
       int sum = 0;
       for (int i = 0; i < 100; i++)
       {
           sum += i;
       }
       throw new Exception("An error occurred.");
       return sum;
   }

   async Task Main()
   {
       try
       {
           int result = await CalculateSumAsync();
           Console.WriteLine(result);
       }
       catch (Exception ex)
       {
           Console.WriteLine(ex.Message);
       }
   }

  在这个例子中,CalculateSumAsync方法在计算总和的过程中抛出了一个异常。在Main方法中,使用try-catch块来捕获这个异常,并在控制台上输出异常消息。

使用 Task.Exception 属性

  Task.Exception属性返回一个AggregateException,其中包含了Task中发生的所有异常。例如:

   Task<int> task = Task.Run(() =>
   {
       int sum = 0;
       for (int i = 0; i < 100; i++)
       {
           sum += i;
       }
       throw new Exception("An error occurred.");
       return sum;
   });

   try
   {
       task.Wait();
       int result = task.Result;
       Console.WriteLine(result);
   }
   catch (AggregateException ex)
   {
       foreach (var innerException in ex.InnerExceptions)
       {
           Console.WriteLine(innerException.Message);
       }
   }

  在这个例子中,task.Wait()方法会阻塞当前线程,直到task完成。如果task中发生了异常,catch块将捕获AggregateException,并遍历其中的所有异常,在控制台上输出异常消息。

五、Task 的延续

使用 ContinueWith 方法

  ContinueWith方法用于在一个Task完成后执行另一个操作。例如:

   Task<int> task = Task.Run(() =>
   {
       int sum = 0;
       for (int i = 0; i < 100; i++)
       {
           sum += i;
       }
       return sum;
   });

   task.ContinueWith(t =>
   {
       Console.WriteLine(t.Result);
   });

  在这个例子中,task.ContinueWith方法在task完成后执行一个 lambda 表达式,该表达式输出task的结果。

使用 await 关键字和异步方法

  也可以使用await关键字和异步方法来实现Task的延续。例如:

   async Task<int> CalculateSumAsync()
   {
       int sum = 0;
       for (int i = 0; i < 100; i++)
       {
           sum += i;
       }
       return sum;
   }

   async Task PrintResultAsync(int result)
   {
       Console.WriteLine(result);
   }

   async Task Main()
   {
       int result = await CalculateSumAsync();
       await PrintResultAsync(result);
   }

  在这个例子中,Main方法首先调用CalculateSumAsync方法,并使用await关键字等待该方法完成。然后,它调用PrintResultAsync方法,并使用await关键字等待该方法完成。这样,PrintResultAsync方法就作为CalculateSumAsync方法的延续执行。

六、Task 的并行执行

使用多个 Task

  可以同时启动多个Task,并等待它们全部完成。例如:

   Task<int> task1 = Task.Run(() =>
   {
       int sum = 0;
       for (int i = 0; i < 100; i++)
       {
           sum += i;
       }
       return sum;
   });

   Task<int> task2 = Task.Run(() =>
   {
       int product = 1;
       for (int i = 1; i <= 10; i++)
       {
           product *= i;
       }
       return product;
   });

   Task.WaitAll(task1, task2);
   int sum = task1.Result;
   int product = task2.Result;
   Console.WriteLine(sum);
   Console.WriteLine(product);

  在这个例子中,同时启动了两个Task,一个计算从 0 到 99 的整数之和,另一个计算从 1 到 10 的整数之积。然后,使用Task.WaitAll方法等待这两个Task全部完成,并输出结果。

使用 Task.WhenAll 方法

  Task.WhenAll方法返回一个Task,当所有传入的Task都完成时,这个Task才完成。例如:

   Task<int> task1 = Task.Run(() =>
   {
       int sum = 0;
       for (int i = 0; i < 100; i++)
       {
           sum += i;
       }
       return sum;
   });

   Task<int> task2 = Task.Run(() =>
   {
       int product = 1;
       for (int i = 1; i <= 10; i++)
       {
           product *= i;
       }
       return product;
   });

   Task<int[]> tasks = Task.WhenAll(task1, task2);
   int[] results = await tasks;
   int sum = results[0];
   int product = results[1];
   Console.WriteLine(sum);
   Console.WriteLine(product);

  在这个例子中,使用Task.WhenAll方法等待两个Task全部完成,并返回一个包含两个Task结果的数组。然后,使用await关键字等待这个Task完成,并输出结果。

七、总结

  Task是 C# 中一种强大的异步编程模型,它允许你在不阻塞主线程的情况下执行耗时的操作。通过使用Task,你可以提高应用程序的响应性和性能,同时保持代码的简洁和可读性。
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/937836.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Scala学习记录

dao --------> 数据访问 mode ------> 模型 service ---->业务逻辑 Main -------> UI:用户直接操作&#xff0c;调用Service 改造UI层&#xff1a;

使用Java得hutool工具实现验证码登录

使用Java的hutool工具实现验证码登录 1.先说一下流程图 2.导入工具包 <dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.8.12</version></dependency>3.流程梳理 3.1前端模版代码 …

java中Map接口的实现类

一、介绍 Map接口常用的实现类有HashMap和TreeMap。HashMap是基于哈希表的Map接口的实现&#xff0c;HashMap类实现的Map集合添加和删除映射关系效率更高。HashMap通过哈希码对其内部的映射关系进行快速查找。TreepMap中的映射关系存在一定的顺序&#xff0c;如果希望Map集合中…

讯飞智文丨一键生成WordPPT

在当今数字化办公的浪潮中,Word和PPT已经成为职场人士日常工作的标配工具。然而,面对繁琐的内容编辑和格式调整任务,如何提升效率成了每个人的追求。而讯飞智文,一款结合人工智能技术的文字处理与演示文稿工具,正逐渐成为用户的得力助手。本文将详细介绍讯飞智文的功能特点…

Dot Foods EDI 需求分析及对接流程

Dot Foods 是一家美国领先的食品和非食品产品的中间批发分销商&#xff0c;主要为食品服务、零售和分销行业的客户提供服务&#xff0c;是北美大型食品中间分销商之一。Dot Foods &#xff08;以下简称 Dot&#xff09;的业务模式是通过整合多个供应商的产品&#xff0c;为客户…

感知机及python实现

感知机&#xff08;Perceptron&#xff09;是神经网络的基本构件之一&#xff0c;最初由Frank Rosenblatt在1957年提出。感知机是一种二分类的线性分类器&#xff0c;通过一个简单的线性函数将输入数据分类到两种类别之一。 基本原理 感知机的工作原理如下&#xff1a; 输入&…

信号滤波分析-低通分析(Matlab)

Matlab低通滤波 信号滤波分析-低通分析&#xff08;Matlab&#xff09; 【标价是仅源码的价格】 【有课程设计答辩PPT和设计文档报告】 需要或感兴趣可以随时联系博主哦&#xff0c;常在线秒回&#xff01; 低通滤波分析方案的设计包括&#xff1a; 1.信号生成原理 2.低通滤波…

ChatGPT客户端安装教程(附下载链接)

用惯了各类AI的我们发现每天打开网页还挺不习惯和麻烦&#xff0c;突然发现客户端上架了&#xff0c;懂摸鱼的人都知道这里面的道行有多深&#xff0c;话不多说&#xff0c;开整&#xff01; 以下是ChatGPT客户端的详细安装教程&#xff0c;适用于Windows和Mac系统&#xff1a…

影像组学+病理组学+深度学习人工智能应用

影像组学 基础学习内容&#xff1a; 特征提取&#xff1a;使用pyradiomics进行形状、纹理、小波变换等特征提取。特征筛选&#xff1a;应用ICC、相关系数、mRMR、Lasso等方法。建模&#xff1a;使用LR、SVM、RF、XGBoost、LightGBM等机器学习算法。模型评估&#xff1a;通过A…

蓝桥杯新年题解 | 第15届蓝桥杯迎新篇

蓝桥杯新年题解 | 第15届蓝桥杯迎新篇 2024年的蓝桥杯即将拉开序幕&#xff01;对于许多编程爱好者来说&#xff0c;这不仅是一次展示自我能力的舞台&#xff0c;更是一次学习和成长的机会。作为一名大一新生的小蓝&#xff0c;对蓝桥杯充满了期待&#xff0c;但面对初次参赛的…

Laplace-Beltrami 拉普拉斯-贝尔特拉米算子

Laplace-Beltrami 拉普拉斯-贝尔特拉米算子 Laplace-Beltrami算子是定义在黎曼流形上的一个二阶微分算子&#xff0c;它在微分几何和偏微分方程中都有重要的应用。在计算机图形学和几何处理中&#xff0c;Laplace-Beltrami算子通常用于网格处理&#xff0c;特别是在网格平滑、…

ISP算法之坏点校正DPC(二):Verilog硬件实现与仿真

DPC的算法讲解和MATLAB仿真参考上一节&#xff1a; ISP算法之坏点校正DPC(一)&#xff1a;MATLAB仿真验证-CSDN博客 本节讲解Verilog的硬件实现与仿真 行缓存设计 DPC算法是基于窗口邻域的像素级别算法&#xff0c;因此需要对实时到来的视频流进行行缓存&#xff0c;行缓存…

clearvoice 语音降噪、语音分离库

参看: https://github.com/modelscope/ClearerVoice-Studio/tree/main ClearVoice 提供了一个统一的推理平台,用于语音增强、语音分离以及视听目标说话人提取。 代码参看: https://github.com/modelscope/ClearerVoice-Studio/tree/main/clearvoice https://github.com/mode…

Linux(网络协议和管理)

后面也会持续更新&#xff0c;学到新东西会在其中补充。 建议按顺序食用&#xff0c;欢迎批评或者交流&#xff01; 缺什么东西欢迎评论&#xff01;我都会及时修改的&#xff01; 在这里真的很感谢这位老师的教学视频让迷茫的我找到了很好的学习视频 王晓春老师的个人空间…

代理 IP 行业现状与未来趋势分析

随着互联网的飞速发展&#xff0c;代理 IP 行业在近年来逐渐兴起并成为网络技术领域中一个备受关注的细分行业。它在数据采集、网络营销、隐私保护等多个方面发挥着重要作用&#xff0c;其行业现状与未来发展趋势值得深入探讨。 目前&#xff0c;代理 IP 行业呈现出以下几个显著…

[Java] 使用 VSCode 来开发 Java

目录 前言Java 环境怎么看自己是否已经配置完成&#xff1f;安装 JDK安装 Maven 环境修改 Maven 依赖源 完善 VS Code配置插件配置 Maven配置 Maven Settings配置 Maven 可执行文件地址 前言 由于使用 VSCode 编码已经成为习惯&#xff0c;并且它确实相对其他的 IDE 较为轻量化…

【热力学与工程流体力学】流体静力学实验,雷诺实验,沿程阻力实验,丘里流量计流量系数测定,局部阻力系数的测定,稳态平板法测定材料的导热系数λ

关注作者了解更多 我的其他CSDN专栏 过程控制系统 工程测试技术 虚拟仪器技术 可编程控制器 工业现场总线 数字图像处理 智能控制 传感器技术 嵌入式系统 复变函数与积分变换 单片机原理 线性代数 大学物理 热工与工程流体力学 数字信号处理 光电融合集成电路…

基于单片机的无绳跳绳设计

基于单片机设计了一款无绳跳绳&#xff0c;采用传感器代替了绳子的摆动&#xff0c;从而实现了模拟跳绳的功能。其研究的方法是&#xff1a;以单片机作为这次设计的核心&#xff0c;它的外围包含有传感器模块、按键模块、显示模块、语音播报模块及电源模块等。本设计采用STM32芯…

暂停一下,给Next.js项目配置一下ESLint(Next+tailwind项目)

前提 之前开自己的GitHub项目&#xff0c;想着不是团队项目&#xff0c;偷懒没有配置eslint&#xff0c;后面发现还是不行。eslint的存在可以帮助我们规范代码格式&#xff0c;同时 ctrl s保存立即调整代码格式是真的很爽。 除此之外&#xff0c;团队使用eslint也是好处颇多…

音频进阶学习八——傅里叶变换的介绍

文章目录 前言一、傅里叶变换1.傅里叶变换的发展2.常见的傅里叶变换3.频域 二、欧拉公式1.实数、虚数、复数2.对虚数和复数的理解3.复平面4.复数和三角函数5.复数的运算6.欧拉公式 三、积分运算1.定积分2.不定积分3.基本的积分公式4.积分规则线性替换法分部积分法 5.定积分计算…