【.NET Core】Task应用详解

简介: 笔记

一、概述


Task(任务)是一个类似于Thead(线程)或ThreadPool(线程池)概念是一个异步执行的工具类。它是一个更轻的类线程工具。Task提供简化编写并发和异步代码的工具类。它包含的类型为Task和Task。TaskFactory类提供用于创建和启动Task任务的静态方法。TaskScheduler类提供默认线程调度基础结构。


Task表示不返回值且通常异步执行的单个操作。Task对象是.NET Framework4中首次引入的基于任务的异步模式的核心组件之一。由于对象执行Task的工作通常在线程池线程上异步执行,而不是在main应用程序线程上同步执行,因此可以使用Statu属性以及IsCanceled、IsCompleted和IsFaulted属性来确定任务的状态。


二、Task用法应用


Task基本使用可以通过New实例化一个Task的应用,也使用通过StartNew来使用Task,还有一种是通过Run使用Task。下面实例通过代码演示三种Task基本的应用。


2.1 通过New实例化Task

Task task1=new Task(()=>{
    Thread.Sleep(1000);
    Debug.WriteLine("执行第一个Task任务.") 
});
Debug.WriteLine($"Task ID"+task1.id)

输出结果:

线程 0x6704 已退出,返回值为 0 (0x0)。
第一个任务ID13
执行第一个Task任务

2.2 通过Factory中StartNew方法

Task task2=new Task(()=>{
    Thread.Sleep(1500);
    Debug.WriteLine("执行第二个Task任务.") 
});
Debug.WriteLine($"Task2 ID"+task2.id);

2.3 通过Run方法

Task task3=new Task(()=>{
   Thread.Sleep(2000);
   Debug.WriteLine("执行第三个Task任务.");
})
Debug.WriteLine($"Task3 ID"+task3.id);

上面三种方法都可以创建一个Task应用。

类Task提供的异常三种创建任务和执行任务的方法。出于性能原因,Task.Run或TaskFactory.StartNew方法是创建和计划计算任务的首选机制,但对于必须分离创建和计划的方案,才考虑使用Task.Start方法计划任务以供以后执行。


三、让Task任务按顺序执行


Task task1 = new Task(() => { 
    Thread.Sleep(1000);
    Debug.WriteLine("执行第一个Task任务");
});
Task task2 = new Task(() => {
    Thread.Sleep(5000);
    Debug.WriteLine("执行第二个Task任务");
});
Task task3 = new Task(() => {
     Thread.Sleep(2000);
     Debug.WriteLine("执行第三个Task任务");
});
Task task4 = new Task(() => {
     Thread.Sleep(1000);
     Debug.WriteLine("执行第四个Task任务");
});
IList<Task> tasks= new List<Task>();
tasks.Add(task1);
tasks.Add(task2);
tasks.Add(task3);
tasks.Add(task4);
foreach (var task in tasks) {
    task.Start();
    task.Wait();
}

如果想要Task按顺序执行,需要给Task加上Wait方法,然后让其阻塞等待完成后在执行下一个Task任务。


四、通过异步Run方法异步执行顺序Task


 public async void RunTask() 
 {
     await Task.Run(async () =>{
         await Task.Delay(1000);
         Debug.WriteLine("第1个线程执行");
     });
     await Task.Run(async () =>{
          await Task.Delay(8000);
          Debug.WriteLine("第2个线程执行");
      });
     await Task.Run(async () =>{
          await Task.Delay(2000);
          Debug.WriteLine("第3个线程执行");
     });
     await Task.Run(async () =>{
          await Task.Delay(3000);
          Debug.WriteLine("第4个线程执行");
     });
}


通过异步await 和async通过 Task.Run创建按次序的Task任务。


五、创建带有返回值的Task


Task和Task暴露静态的Factory属性,该属性返回一个默认的TaskFactory实例,以便调用Task.Factory.StartNew()方法。Task和Taste有一个属性Result属性,该属性包含了运算的结果。任务是异步运行的,可能以任意时序执行完。若Result属性在运行结束前被访问,这个属性会阻塞调用线程到该值可访问。

public async void RunTask() 
{
      Task<Double>[] taskArray = { 
          Task<Double>.Factory.StartNew(() => DoComputation(10.0)),
          Task<Double>.Factory.StartNew(() => DoComputation(100.0)),
          Task<Double>.Factory.StartNew(() => DoComputation(1000.0)) 
      };
      foreach (var task in taskArray)
      {
           double result = task.Result;
           Debug.WriteLine(result);
      }
}

六、Task常用的属性与方法


6.1 AsyncStates属性

获取在创建Task时提供的状态对象,如果未提供,则为null。


6.2 CompletedTask属性

获取一个已成功的任务


6.2 CurrentId属性

返回当前正在执行Task的ID


6.3 Factory属性

提供对用于创建和配置Task和Task实例的工厂方法的访问


6.4 Id属性

获取此Task实例的ID


6.5 IsCanceled属性

获取此Task实例是否由于被取消的原因而完成执行


6.6 IsCompleted属性

获取一个值,它表示是否已完成任务


6.7 IsCompletedSuccessfully属性

了解任务是否运行到完成


6.7 IsFaulted属性

获取Task是否由于未经处理异常的原因而完成


6.8 Status属性

表示Task的生命周期中的当前阶段


  • 0 = Created 该任务已初始化,但尚未被计划
  • 1 = WaitingForActivation 该任务正在等待 .NET 基础结构在内部将其激活并进行计划。
  • 2 = WaitingToRun 该任务已被计划执行,但尚未开始执行
  • 3 = Running 该任务正在运行,但尚未完成
  • 4 = WaitingForChildrenToComplete 该任务已完成执行,正在隐式等待附加的子任务完成
  • 5 = RanToCompletion 已成功完成执行的任务
  • 6 = Canceled 该任务已通过对其自身的 CancellationToken 引发 OperationCanceledException 对取消进行了确认,此时该标记处于已发送信号状态;或者在该任务开始执行之前,已向该任务的 CancellationToken 发出了信号
  • 7 = Faulted 由于未处理异常的原因而完成的任务


6.9 ConfigureAwait(Boolean) 方法

配置用于等待此Task的awaiter


6.10 ContinueWith(Action,Object,TaskScheduler) 方法

创建一个在目标Task完成时接收调用方提供的状态信息和取消标记并执行的延续任务。延续任务根据一组指定的条件执行,并使用指定的计划程序。


6.11 Delay(TimeSpan,CancellationToken) 方法

创建一个在指定的毫秒数后完成的可取消任务或创建一个指定的时间间隔后完成的可取消的任务。


6.12 Run(Action,CancellationToken) 方法

将在线程池上运行的指定工作排队,并返回代表该工作的 Task对象。 可使用取消标记来取消工作(如果尚未启动)。


6.13 Start(TaskScheduler) 方法

启动Task, 并将它安排到当前的TaskScheduler中执行


6.14 Wait(Task[],CancellationToken) 方法

等待提供的所有Task对象在指定的毫秒数内完成执行,或等到取消等待


6.15 Yield()方法

创建异步产生当前上下文的等待任务。


七、Task总结


Task是并行编程的一个重要的特性,主要的特点有一下几点:


  • 底层是在线程池中运作的,且微软用了一些增强性能的算法(这点使你在大部分场景中可以无忧地使用它)
  • 实际使用往往会结合lambda表达式
  • 结合lambda表达式在循环中使用计数器时,需要注意lambda内使用计数器是其引用。可以使用自定义传参给任务来回避这种情况

在实际的开发中还需要根据实际的应用场景,选项合适的属性和方法,希望你通过本文能完全掌握Task的应用。


七、参考资料


https://learn.microsoft.com/zh-cn/dotnet/standard/parallel-programming/task-parallel-library-tpl

目录
相关文章
|
2月前
|
存储 Shell Linux
快速上手基于 BaGet 的脚本自动化构建 .net 应用打包
本文介绍了如何使用脚本自动化构建 `.net` 应用的 `nuget` 包并推送到指定服务仓库。首先概述了 `BaGet`——一个开源、轻量级且高性能的 `NuGet` 服务器,支持多种存储后端及配置选项。接着详细描述了 `BaGet` 的安装、配置及使用方法,并提供了 `PowerShell` 和 `Bash` 脚本实例,用于自动化推送 `.nupkg` 文件。最后总结了 `BaGet` 的优势及其在实际部署中的便捷性。
126 10
|
1月前
|
存储 开发框架 JSON
ASP.NET Core OData 9 正式发布
【10月更文挑战第8天】Microsoft 在 2024 年 8 月 30 日宣布推出 ASP.NET Core OData 9,此版本与 .NET 8 的 OData 库保持一致,改进了数据编码以符合 OData 规范,并放弃了对旧版 .NET Framework 的支持,仅支持 .NET 8 及更高版本。新版本引入了更快的 JSON 编写器 `System.Text.UTF8JsonWriter`,优化了内存使用和序列化速度。
|
9天前
|
开发框架 监控 .NET
【Azure App Service】部署在App Service上的.NET应用内存消耗不能超过2GB的情况分析
x64 dotnet runtime is not installed on the app service by default. Since we had the app service running in x64, it was proxying the request to a 32 bit dotnet process which was throwing an OutOfMemoryException with requests >100MB. It worked on the IaaS servers because we had the x64 runtime install
|
23天前
|
JSON 算法 安全
JWT Bearer 认证在 .NET Core 中的应用
【10月更文挑战第30天】JWT(JSON Web Token)是一种开放标准,用于在各方之间安全传输信息。它由头部、载荷和签名三部分组成,用于在用户和服务器之间传递声明。JWT Bearer 认证是一种基于令牌的认证方式,客户端在请求头中包含 JWT 令牌,服务器验证令牌的有效性后授权用户访问资源。在 .NET Core 中,通过安装 `Microsoft.AspNetCore.Authentication.JwtBearer` 包并配置认证服务,可以实现 JWT Bearer 认证。具体步骤包括安装 NuGet 包、配置认证服务、启用认证中间件、生成 JWT 令牌以及在控制器中使用认证信息
|
24天前
.NET 4.0下实现.NET4.5的Task类相似功能组件
【10月更文挑战第29天】在.NET 4.0 环境下,可以使用 `BackgroundWorker` 类来实现类似于 .NET 4.5 中 `Task` 类的功能。`BackgroundWorker` 允许在后台执行耗时操作,同时不会阻塞用户界面线程,并支持进度报告和取消操作。尽管它有一些局限性,如复杂的事件处理模型和不灵活的任务管理方式,但在某些情况下仍能有效替代 `Task` 类。
|
2月前
|
开发框架 监控 前端开发
在 ASP.NET Core Web API 中使用操作筛选器统一处理通用操作
【9月更文挑战第27天】操作筛选器是ASP.NET Core MVC和Web API中的一种过滤器,可在操作方法执行前后运行代码,适用于日志记录、性能监控和验证等场景。通过实现`IActionFilter`接口的`OnActionExecuting`和`OnActionExecuted`方法,可以统一处理日志、验证及异常。创建并注册自定义筛选器类,能提升代码的可维护性和复用性。
|
2月前
|
开发框架 .NET 中间件
ASP.NET Core Web 开发浅谈
本文介绍ASP.NET Core,一个轻量级、开源的跨平台框架,专为构建高性能Web应用设计。通过简单步骤,你将学会创建首个Web应用。文章还深入探讨了路由配置、依赖注入及安全性配置等常见问题,并提供了实用示例代码以助于理解与避免错误,帮助开发者更好地掌握ASP.NET Core的核心概念。
95 3
|
1月前
|
开发框架 JavaScript 前端开发
一个适用于 ASP.NET Core 的轻量级插件框架
一个适用于 ASP.NET Core 的轻量级插件框架
|
2月前
|
数据采集 JSON API
.NET 3.5 中 HttpWebRequest 的核心用法及应用
【9月更文挑战第7天】在.NET 3.5环境下,HttpWebRequest 类是处理HTTP请求的一个核心组件,它封装了HTTP协议的细节,使得开发者可以方便地发送HTTP请求并接收响应。本文将详细介绍HttpWebRequest的核心用法及其实战应用。
124 6
|
2月前
|
开发框架 NoSQL .NET
利用分布式锁在ASP.NET Core中实现防抖
【9月更文挑战第5天】在 ASP.NET Core 中,可通过分布式锁实现防抖功能,仅处理连续相同请求中的首个请求,其余请求返回 204 No Content,直至锁释放。具体步骤包括:安装分布式锁库如 `StackExchange.Redis`;创建分布式锁服务接口及其实现;构建防抖中间件;并在 `Startup.cs` 中注册相关服务和中间件。这一机制有效避免了短时间内重复操作的问题。