C#如何使用Task执行异步操作

作者:HarryK 时间:2023-01-12 03:34:41 

目录
  • 为什么要使用 Task

  • Task 和 Thread 区别

  • Task 介绍

  • Task 简单实现

  • Task 执行状态

    • 1.等待(Wait)

    • 2. 返回值

    • 3. Task.Delay

为什么要使用 Task

线程是创建并发的底层工具,因此具有一定的局限性。

  • 没有简单的方法可以从联合(Join)线程得到“返回值”。因此必须创建一些共享域。当抛出一个异常时,捕捉和处理异常也是麻烦的。

  • 线程完成之后,无法再次启动该线程。相反,只能联合(Join)它(在进程阻塞当前线程)。

任务是可组合的——使用延续将它们串联在一起。它们可以使用线程池减少启动延迟,而且它们可以通过TaskCompletionSource使用回调方法,避免多个线程同时等待I/O密集操作。

Task 和 Thread 区别

1、任务是架构在线程之上的,也就是说任务最终还是要抛给线程去执行。

2、任务跟线程不是一对一的关系,比如开10个任务并不是说会开10个线程,这一点任务有点类似线程池,但是任务相比线程池有很小的开销和精确的控制。

Task和Thread一样,位于System.Threading命名空间下

与线程相比,Task是一个更高级的抽象概念,它标识一个通过或不通过线程实现的并发操作。

Task 介绍

Task 类的表示单个操作不返回一个值,通常以异步方式执行。 Task 对象是一个的中心思想 基于任务的异步模式 首次引入.NET Framework 4 中。 因为由执行工作 Task 对象通常以异步方式执行在线程池线程上而不是以同步方式在主应用程序线程,您可以使用 Status 属性,以及 IsCanceled, ,IsCompleted, ,和 IsFaulted 属性,以确定任务的状态。 大多数情况下,lambda 表达式用于指定的任务是执行的工作。

Task 简单实现

通过使用Task的构造函数来创建任务,并调用Start方法来启动任务并执行异步操作。


static void Main(string[] args)
{
       Console.WriteLine("主线程执行业务处理.");
       //创建任务
       Task task = new Task(() => {
           Console.WriteLine("使用System.Threading.Tasks.Task执行异步操作.");
           for (int i = 0; i < 10; i++)
           {
                 Console.WriteLine(i);
           }
     });
    //启动任务,并安排到当前任务队列线程中执行任务
     task.Start();
     Console.WriteLine("主线程执行其他处理");
}

从Framework 4.5开始,启动一个由后台线程实现的Task,也可以使用静态方法 Task.Run


Task task = Task.Run(() =>
   {
       Thread.Sleep(2000);
       Console.WriteLine("Foo");
   });

Task默认使用线程池,它们都是后台线程。意味当主线程结束时,所有任务都会随之停止。

Task 执行状态

1.等待(Wait)

调用Wait方法,可以阻塞任务,直至任务完成,效果等同于Thread.Join:


Task task = Task.Run(() =>
   {
       Thread.Sleep(2000);
       Console.WriteLine("Foo");
   });
   Console.WriteLine(task.IsCompleted); //False
   task.Wait();//阻塞,直至任务完成
   Console.WriteLine(task.IsCompleted); //True
   Console.ReadLine();

2. 返回值

Task<TResult>允许任务返回一个值。调用Task.Run,传入一个Func<TResult>代理(或者兼容的Lambda表达式),代替Action,就可以获得一个Task<TResult>:


Task<int> task = Task.Run (() => { Console.WriteLine ("Foo"); return 3; });

int result = task.Result;      // Blocks if not already finished
Console.WriteLine (result);    // 3

下面的例子创建一个任务,它使用LINQ就按前3百万个整数(从2开始)中的素数个数:


Task<int> primeNumberTask = Task.Run(() =>
       Enumerable.Range(2, 3000000).Count(n => Enumerable.Range(2, (int)Math.Sqrt(n) - 1).All(i => n % i > 0)));

Console.WriteLine("Task running...");
   Console.WriteLine("The answer is " + primeNumberTask.Result);

这段代码会打印“Task running...”,然后几秒钟后打印216815。

3. Task.Delay

Task.Delay是Thread.Sleep的异步版本


Task.Delay(5000).GetAwaiter().OnCompleted(()=>Console.WriteLine(42));

或者


Task.Delay(5000).ContinueWith(ant => Console.WriteLine(42));

来源:https://www.cnblogs.com/HarryK4952/p/14716829.html

标签:c#,Task,异步操作
0
投稿

猜你喜欢

  • 详解Java双轴快速排序算法

    2023-10-05 15:50:14
  • SpringBoot项目中使用Mockito的示例代码

    2023-09-25 22:31:14
  • C++集体数据交换实现示例讲解

    2023-12-17 11:35:07
  • Mybatis 逆向工程的三种方法详解

    2023-08-10 22:27:20
  • c#日期间隔计算示例

    2022-11-28 07:49:48
  • Spring MVC+FastJson+hibernate-validator整合的完整实例教程

    2021-10-31 13:20:13
  • C#通过抽象工厂模式造车

    2021-07-05 04:20:55
  • Java接口统一样式返回模板简介

    2022-10-31 19:50:43
  • Android Parcleable接口的调用源码层分析

    2023-07-09 20:43:48
  • C#中使用split分割字符串的几种方法小结

    2023-06-18 17:23:21
  • Android设计模式之单例模式详解

    2022-03-12 16:51:47
  • kotlin浅析when与循环的使用

    2022-01-13 01:23:57
  • C#编程和Visual Studio使用技巧(上)

    2021-10-01 00:54:27
  • SpringCloud超详细讲解微服务网关Gateway

    2021-09-11 14:54:49
  • springboot基于docsify 实现随身文档

    2023-04-25 04:52:23
  • Android调试华为和魅族手机logcat不显示的问题

    2023-12-06 04:17:55
  • JFreeChart插件实现的折线图效果实例

    2023-09-21 02:20:03
  • C#实现彻底删除文件的方法

    2022-06-25 22:40:29
  • JAVA实现心跳检测(长连接)

    2022-12-16 04:26:30
  • Android实现手势滑动多点触摸放大缩小图片效果

    2022-02-13 09:26:28
  • asp之家 软件编程 m.aspxhome.com