首页 > 编程语言 >C# 使用Task执行异步操作

C# 使用Task执行异步操作

时间:2023-11-26 10:12:10浏览次数:38  
标签:异步 Task Console C# 任务 线程 WriteLine

原文链接:C# 使用Task执行异步操作 - Ryan_zheng - 博客园 (cnblogs.com)

为什么要使用 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.DelayThread.Sleep的异步版本

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

或者

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

原文链接:C# 使用Task执行异步操作 - Ryan_zheng - 博客园 (cnblogs.com)

标签:异步,Task,Console,C#,任务,线程,WriteLine
From: https://www.cnblogs.com/sunhouzi/p/17856572.html

相关文章

  • python 将docx按页分割
    Python将docx按页分割在进行文档处理过程中,有时我们需要将一个大的docx文件按页分割成多个小文件,这样可以更方便地处理、管理和查看文档内容。本文将介绍如何使用Python来实现这个功能,并提供相应的代码示例。docx文档格式简介在开始介绍具体的代码实现之前,我们先来了解一下docx......
  • 试题 D: 本质上升序列(C/C++)
    题目描述:小蓝特别喜欢单调递增的事物。在一个字符串中,如果取出若干个字符,将这些字符按照在字符串中的顺序排列后是单调递增的,则成为这个字符串中的一个单调递增子序列。例如,在字符串lanqiao中,如果取出字符n和q,则nq组成一个单调递增子序列。类似的单调递增子序列还有lnq......
  • 统计指定月份的总金额,用SUMPRODUCT函数快速解决!
    1职场实例小伙伴们大家好,今天我们来讲解一个关于SUMPRODUCT函数解决指定月份汇总金额的职场真实案例。如下图所示:是一张每日的产品数量单价明细表格。A列为日期,B列为数量,C列为单价,数量乘以单价即为当天的总金额,但是总金额数据在数据源中是没有体现出来的。我们想要在F2单元格汇总出......
  • Clion的中文编码问题
    此文章用于解决Clion编译源代码后运行显示乱码问题!首先打开设:全部改为UTF-8再将文件的编码改为GBK:最后运行:......
  • Eslint 的rules一些配置 (.eslintrc.js文件中的rules选项)
    rules:{//off=0,warn=1,error=2,如果是数组,第二项表示参数option//indent:[2,2],//控制缩进为2eqeqeq:1,//警告使用全等//quotes:[2,'single'],//单引号singleQuote:true,'no-console':0,//不禁用console'no-debugger......
  • 使用skforecast进行时间序列预测
    时间序列预测是数据科学和商业分析中基于历史数据预测未来价值的一项重要技术。它有着广泛的应用,从需求规划、销售预测到计量经济分析。由于Python的多功能性和专业库的可用性,它已经成为一种流行的预测编程语言。其中一个为时间序列预测任务量身定制的库是skforecast。在本文中,将......
  • Educational Codeforces Round 158 (Rated for Div. 2)
    EducationalCodeforcesRound158(RatedforDiv.2)基本情况A题很水,几分钟秒了。B题想到一个解,被自己hack掉之后没有重新想,一直想在自己一开始的基础上改好,结果最后B都没拿下。B.ChipandRibbon我的思路其实也是找规律,根本没严谨地证明正确性。不应该一条路走到黑的......
  • Docker部署思源笔记
    一、简介思源笔记是一款隐私优先的个人知识管理系统,支持细粒度块级引用和Markdown所见即所得。二、安装思源笔记绿联DX4600为例。首先我们打开Docker管理器,进入镜像管理。然后在镜像仓库中搜索b3log/siyuan​​,选择latest​​版本并下载。​​下载完成后,我们在本地镜......
  • .net core下优秀的日志框架使用解析,附源代码
    在.NETCore中,日志是一个非常重要的组件,它可以帮助我们记录应用程序的运行情况,以便在出现问题时进行排查。在本文中,我们将介绍五个优秀的.NETCore日志框架,它们分别是Serilog、NLog、Log4Net、Microsoft.Extensions.Logging和Loupe。我们将为每个框架提供使用方法及步骤,并......
  • huggingface_hub.utils._validators.HFValidationError: Repo id must be in the form
    问题:2023-11-2607:45:38|ERROR|stderr|raiseHFValidationError(2023-11-2607:45:38|ERROR|stderr|huggingface_hub.utils._validators.HFValidationError:Repoidmustbeintheform'repo_name'or'namespace/repo_name':'/mnt......