首页 > 编程语言 >C#Task任务类

C#Task任务类

时间:2024-11-18 09:17:28浏览次数:3  
标签:Task Thread C# isRuning t2 t1 任务 print

目录

前言

认识Task

创建无返回值Task的三种方式

第一种方式

第二种方式

第三种方式

返回有返回值的Task

第一种方式

第二种方式

第三种方式

同步执行Task

Task中线程阻塞的方式

Task完成后继续其它Task(任务延续)

取消Task执行

总结


前言

Task类是.NET平台上进行多线程和异步操作的重要工具。它提供了简洁而强大的API支持,使得开发者能够更加高效地利用系统资源,实现复杂的并行和异步操作。无论是在I/O密集型操作还是CPU密集型任务中,Task类都能为开发者提供有力的支持。

认识Task

命名空间:System.Threading.Tasks
类名:Task
Task顾名思义就是任务的意思
Task是在线程池基础上进行的改进,它拥有线程池的优点,同时解决了使用线程池不易控制的弊端。
它是基于线程池的优点对线程的封装,可以让我们更方便高效的进行多线程开发。

简单理解:
Task的本质是对线程Thread的封装,它的创建遵循线程池的优点,并且可以更方便的让我们控制线程。
一个Task对象就是一个线程。


创建无返回值Task的三种方式

第一种方式

通过new一个Task对象传入委托函数并启动

        Task t1 = new Task(() =>
        {
            int i = 0;
            while (isRuning)
            {
                print("方式一:" + i);
                ++i;
                Thread.Sleep(1000);
            }
        });
        t1.Start();

第二种方式

通过Task中的Run静态方法传入委托函数

        Task t2 = Task.Run(() =>
        {
            int i = 0;
            while (isRuning)
            {
                print("方式二:" + i);
                ++i;
                Thread.Sleep(1000);
            }
        });

第三种方式

通过Task.Factory中的StartNew静态方法传入委托函数

Task t3 = Task.Factory.StartNew(() =>
{
    int i = 0;
    while (isRuning)
    {
        print("方式三:" + i);
        ++i;
        Thread.Sleep(1000);
    }
});


返回有返回值的Task

第一种方式

 通过new一个Task对象闯入委托函数并启动

t1 = new Task<int>(() =>
{
    int i = 0;
    while (isRuning)
    {
        print("方式一:" + i);
        ++i;
        Thread.Sleep(1000);
    }
    return 1;
});
t1.Start();

第二种方式

通过Task中的Run静态方法传入委托函数

t2 = Task.Run<string>(() =>
{
    int i = 0;
    while (isRuning)
    {
        print("方式二:" + i);
        ++i;
        Thread.Sleep(1000);
    }
    return "1231";
});

第三种方式

通过Task.Factory中的StartNew静态方法传入委托函数

t3 = Task.Factory.StartNew<float>(() =>
{
    int i = 0;
    while (isRuning)
    {
        print("方式三:" + i);
        ++i;
        Thread.Sleep(1000);
    }
    return 4.5f;
});

获取返回值
注意:
Resut获取结果时会阻塞线程
即如果task没有执行完成
会等待task执行完成获取到Result
然后再执行后边的代码,也就是说 执行到这句代码时 由于我们的Task中是死循环 
所以主线程就会被卡死


同步执行Task

之前我们举的例子都是通过多线程异步执行的
如果希望Task能够同步执行
只需要调用Task对象中的RunSynchronously方法
注意:需要使用 new Task对象的方式,因为Run和StartNew在创建时就会启动

        Task t = new Task(() =>
        {
            Thread.Sleep(1000);
            print("这是一段话");
        });
        //t.Start();
        t.RunSynchronously();
        print("主线程执行");

不Start 而是 RunSynchronously


Task中线程阻塞的方式

1.Wait方法:等待任务执行完毕,再执行后面的内容

 Task t1 = Task.Run(() =>
 {
     for (int i = 0; i < 5; i++)
     {
         print("t1:" + i);
     }
 });

 Task t2 = Task.Run(() =>
 {
     for (int i = 0; i < 20; i++)
     {
         print("t2:" + i);
     }
 });

//t2.Wait();

2.WaitAny静态方法:传入任务中任意一个任务结束就继续执行
Task.WaitAny(t1, t2);

3.WaitAll静态方法:任务列表中所有任务执行结束就继续执行
Task.WaitAll(t1, t2);


Task完成后继续其它Task(任务延续)

 1.WhenAll静态方法 + ContinueWith方法:传入任务完毕后再执行某任务

using System.Threading;
using System.Threading.Tasks;
using UnityEngine;

public class Test : MonoBehaviour
{
    Task t1,t2;

    bool isRuning =true;
    void Start()
    {
        Task.WhenAll(t1, t2).ContinueWith((t) =>
        {
            print("一个新的任务开始了");
            int i = 0;
            while (isRuning)
            {
                print(i);
                ++i;
                Thread.Sleep(1000);
            }
        });

        Task.Factory.ContinueWhenAll(new Task[] { t1, t2 }, (t) =>
        {
            print("一个新的任务开始了");
            int i = 0;
            while (isRuning)
            {
                print(i);
                ++i;
                Thread.Sleep(1000);
            }
        });

    }
    private void OnDestroy()
    {
        isRuning = false;
    }
}

2.WhenAny静态方法 + ContinueWith方法:传入任务只要有一个执行完毕后再执行某任务 

using System.Threading;
using System.Threading.Tasks;
using UnityEngine;

public class Test : MonoBehaviour
{
    Task t1,t2;

    bool isRuning =true;
    void Start()
    {
        Task.WhenAny(t1, t2).ContinueWith((t) =>
        {
            print("一个新的任务开始了");
            int i = 0;
            while (isRuning)
            {
                print(i);
                ++i;
                Thread.Sleep(1000);
            }
        });

        Task.Factory.ContinueWhenAny(new Task[] { t1, t2 }, (t) =>
        {
            print("一个新的任务开始了");
            int i = 0;
            while (isRuning)
            {
                print(i);
                ++i;
                Thread.Sleep(1000);
            }
        });

    }
    private void OnDestroy()
    {
        isRuning = false;
    }
}

取消Task执行

方法一:通过加入bool标识 控制线程内死循环的结束

方法二:通过CancellationTokenSource取消标识源类 来控制
CancellationTokenSource对象可以达到延迟取消、取消回调等功能

using System.Threading;
using System.Threading.Tasks;
using UnityEngine;

public class Test : MonoBehaviour
{
    Task t1,t2;

    CancellationTokenSource c;
    void Start()
    {
        c = new CancellationTokenSource();
        //延迟取消
        c.CancelAfter(5000);
        //取消回调
        c.Token.Register(() =>
        {
            print("任务取消了");
        });
        Task.Run(() =>
        {
            int i = 0;
            while (!c.IsCancellationRequested)
            {
                print("计时:" + i);
                ++i;
                Thread.Sleep(1000);
            }
        });

    }
    private void OnDestroy()
    {
        c.Cancel();
    }
}

总结

1.Task类是基于Thread的封装
2.Task类可以有返回值,Thread没有返回值
3.Task类可以执行后续操作,Thread没有这个功能
4.Task可以更加方便的取消任务,Thread相对更加单一
5.Task具备ThreadPool线程池的优点,更节约性能

标签:Task,Thread,C#,isRuning,t2,t1,任务,print
From: https://blog.csdn.net/weixin_67674686/article/details/143591214

相关文章

  • PbootCMS留言记录列表
    {pboot:messagenum=*}<p>[message:contacts]</p><p>[message:content]</p>{/pboot:message}调取的留言记录:默认执行分页,使用内容列表的分页代码即可。内容隐私:使用截取功能,例如 [message:mobilesubstr=1,3]****[message:mobilesubstr=8] 输出效果:187****......
  • class not found Runtime/~runtime.php
    问题分析原因:ThinkPHP站点的缓存目录 Runtime 从其他服务器迁移至云虚拟主机时,可能包含了一些不兼容的缓存文件或目录信息,导致类文件无法被正确加载。解决方案:删除或重命名 Runtime 目录,让ThinkPHP重新生成新的缓存文件。操作步骤登录云虚拟主机使用SSH工具(如PuTTY)......
  • 【人脸伪造检测】Self-Supervised Video Forensics by Audio-Visual Anomaly Detectio
    一、研究动机[!note]原理:经过处理后的视频在视觉和音频信号之间通常会有不一致的现象,提出一种基于异常检测算法实现视频伪造取证。挑战:不同于简单的检测不同步的例子,因为由于视频采集往往会有“延迟”现象,出现帧偏移现象创新点:提出在视听特征中实现异常检测,该特征包含了视听......
  • HarmonyOS Next 椭圆曲线密码学应用:ECC 与 SM2 深入剖析
    本文旨在深入探讨华为鸿蒙HarmonyOSNext系统(截止目前API12)的技术细节,基于实际开发实践进行总结。主要作为技术分享与交流载体,难免错漏,欢迎各位同仁提出宝贵意见和问题,以便共同进步。本文为原创内容,任何形式的转载必须注明出处及原作者。一、引言在现代密码学领域,椭圆曲线密......
  • MariaDB Galera Cluster集群搭建
    MariaDBGaleraCluster是什么?   GaleraCluster是由第三方公司Codership所研发的一套免费开源的集群高可用方案,实现了数据零丢失,官网地址为http://galeracluster.com/其在MySQLInnoDB存储引擎基础上打了wrep(虚拟全同步复制),Percona/MariaDB已捆绑在各自的发行版本中Maria......
  • 第三篇Scrum冲刺博客
    第三篇Scrum冲刺博客会议图【这里需要一个会议图】昨日实际完成任务汇总昨日已完成任务详细内容实际用时分析现有架构对项目当前的数据库架构进行全面分析,找出存在的瓶颈和问题。4数据库维护与监控确保数据库的稳定运行,及时发现并解决潜在问题,提高系统的可靠......
  • C2 追踪器:监控指挥与控制的重要性
    12款暗网监控工具20款免费网络安全工具移动取证软件:为什么BelkasoftX应该是您的首选工具网络安全已成为不断演变的威胁形势中的关键领域。网络攻击者经常使用命令和控制(C2)基础设施来执行和管理攻击。这些基础设施使恶意软件和攻击者能够与受害设备进行通信。C......
  • 异常值检测:SOS算法(Stochastic Outlier Selection Algorithm)MATLAB代码
    SOS算法(StochasticOutlierSelectionAlgorithm)是由JeroenJanssens提出的一种无监督异常检测算法。该算法通过计算数据点之间的关联度(affinity)来识别异常点。核心思想是,如果一个点与其他所有点的关联度都很低,那么它被视为异常点。以下是该算法的详细公式和步骤:其MATLAB代码......
  • 第四篇Scrum冲刺博客
    第四篇Scrum冲刺博客会议图【这里需要一个会议图】昨日实际完成任务汇总昨日已完成任务详细内容实际用时前端界面设计设计视频推荐页面,包括视频卡片、分类、标签等元素的布局。5后端接口开发开发视频推荐与展示接口,从数据库中获取视频数据,并返回给前端。3......
  • 第五篇Scrum冲刺博客
    第五篇Scrum冲刺博客一、站立式会议二、完成进度昨天完成的任务与今天计划完成任务成员昨天完成任务今天计划完成任务李明佳设计视频投稿页面设计用户个人信息修改界面韩冠熙开发视频审核流程开发用户个人作品展示与管理功能王钦鹏开发视频上传功能开......