前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >C# TASK使用实例

C# TASK使用实例

作者头像
zls365
发布于 2020-08-19 06:44:00
发布于 2020-08-19 06:44:00
1.3K00
代码可运行
举报
文章被收录于专栏:CSharp编程大全CSharp编程大全
运行总次数:0
代码可运行
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WindowsFormsApp3
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            Task.Run(()=>
            {
                for (int i = 0; i < 500000000; i++)  //比较耗时的任务放到task中区执行,不然定时器等到此任务执行完才会更新界面数据
                {
                    Task th1 = new Task(test1);
                    th1.Start();
                    Task th2 = new Task(test2);
                    th2.Start();
                }
            });

        }
        int ca = 0;
        object locker = new object();
        private void test1()
        {

                lock (locker)  //由于多个task存在数据竞争,需要加锁
                {
                    this.BeginInvoke(new Action(() => {  label1.Text =  ca.ToString() + " 秒"; }));
                    ca++;
                    Thread.Sleep(1000);
                }

        }
        private void test2()
        {

            lock (locker) //由于多个task存在数据竞争,需要加锁
            {
                this.BeginInvoke(new Action(() => { label1.Text =  ca.ToString() + " 秒"; }));
                ca++;
                Thread.Sleep(1000);
            }

        }
    }
}

运行结果:

Task的用法

  1、创建任务

(一)无返回值的方式 方式1:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制

  var t1 = new Task(() => TaskMethod("Task 1"));
  t1.Start();
  Task.WaitAll(t1);//等待所有任务结束 
  注:任务的状态:
  Start之前为:Created
  Start之后为:WaitingToRun 

方式2:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
  Task.Run(() => TaskMethod("Task 2"));

  方式3:

代码语言:javascript
代码运行次数:0
运行
复制
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
  Task.Factory.StartNew(() => TaskMethod("Task 3")); 直接异步的方法 
  //或者
  var t3=Task.Factory.StartNew(() => TaskMethod("Task 3"));
  Task.WaitAll(t3);//等待所有任务结束
  //任务的状态:
  Start之前为:Running
  Start之后为:Running

2.Task的使用简单总结

1、首次构造一个Task对象时,他的状态是Created。

2、当任务启动时,他的状态变成WaitingToRun。

3、Task在一个线程上运行时,他的状态变成Running。

4、任务停止运行,等待他的任何子任务时,状态变成WaitingForChildrenToComplete。

5、任务完全结束时,它进入以下三个状态之一:RanToCompletion,Canceled或者Faulted。

6、一个Task<TResult>运行完成时,可通过Task<TResult>的Result属性来查询任务的结果,

7、一个Task或者Task<TResult>出错时,可以查询Task的Exception属性来获得任务抛出的未处理的异常,该属性总是返回一个AggregateException对象,他包含所有未处理的异常。

8、为简化代码,Task提供了几个只读的Boolean属性,IsCanceled,IsFaulted,IsCompleted。

9、注意,当Task处于RanToCompleted,Canceled或者Faulted状态时,IsCompleted返回True。

10、为了判断一个Task是否成功完成,最简单的方法是:if(task.Status == TaskStatus.RanToCompletion)。

11、task的ContinueWith方法用于在一个任务完成后发起一个新任务。

12、任务的启动、停止与异常处理

(1)任务的启动:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
CancellationTokenSource cts = new CancellationTokenSource();
Task task = new Task(() => ThreadGetData(cts.Token), cts.Token);
private void ThreadGetData(CancellationToken ct)//ThreadGetData是自己的一个方法,用于每分钟读取一次数据
{
ReadDataOneMinite(ct);
}
task.Start()//任务启动

(2)任务的停止:

任务和线程并不是调用者想停止就能停止的,正确停止线程更多地在于工作线程是否能主动响应调用者的停止请求。在基于Task的任务执行过程中,我们通常使用CancellationTokenSource来实现任务取消。CancellationTokenSource 是一种名为“取消标记”的轻型对象,用于线程和任务的协作取消。线程和任务在工作的同时,会以某种频率检测CancellationTokenSource的IsCancellationRequested标识,若检测到IsCancellationRequested,线程自己负责退出。下面是线程取消的一段代码示例:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
CancellationTokenSource
cts =
new CancellationTokenSource();
Task task =
new Task(()
=>
{
while (true)
{
if (cts.Token.IsCancellationRequested)//如果检测到取消请求
{
Console.WriteLine("线程被终止!");
break;
}
//否则执行某工作

ReadDataOneMinite(ct);//用于每分钟读取一次数据
Thread.Sleep(60000);
}
});
task.Start();
cts.Cancel();//任务取消

调用者使用CancellationTokenSource的Cancle方法通知工作线程退出。工作线程则以大致60000毫秒的频率一边工作,一边检查是否有外界传入进来的Cancel信号。若有这样的信号,则负责退出。协作式取消中的关键类型是CancellationTokenSource。它有一个关键属性Token,Token是一个名为CancellationToken的值类型。CancellationToken继而进一步提供了布尔值的属性IsCancellationRequested作为需要取消工作的标识。

(3)任务的异常处理:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
CancellationTokenSource cts
=
new CancellationTokenSource();
Task
task =
new Task(()
=>
{
while (true)
{
if (cts.Token.IsCancellationRequested)//如果检测到取消请求
{
cts.Token.ThrowIfCancellationRequested();//异常处理来退出程序,但CLR知道这一行是程序员有意为之,所以并不
把它当做一个异常(它被理解为取消)
break;
}
//否则执行某工作

ReadDataOneMinite(ct);//用于每分钟读取一次数据
Thread.Sleep(60000);
}
});

以上是一些简单的使用方式,待工作中深入应用后再进行补充任务的其他使用。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-04-28,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 CSharp编程大全 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
【推荐】C#线程篇---Task(任务)和线程池不得不说的秘密(5.1)
在上篇最后一个例子之后,我们发现了怎么去使用线程池,调用ThreadPool的QueueUserWorkItem方法来发起一次异步的、计算限制的操作,例子很简单,不是吗?   然而,在今天这篇博客中,我们要知道的是,QueueUserWorkItem这个技术存在许多限制。其中最大的问题是没有一个内建的机制让你知道操作在什么时候完成,也没有一个机制在操作完成是获得一个返回值,这些问题使得我们都不敢启用这个技术。   Microsoft为了克服这些限制(同时解决其他一些问题),引入了任务(tasks)的概念。顺
逸鹏
2018/04/10
1.6K0
【推荐】C#线程篇---Task(任务)和线程池不得不说的秘密(5.1)
如何取消.net后台线程的执行
介绍 在使用多线程模型进行编程时,经常遇到的问题之一是,当我们关闭前台的UI线程时,后台的辅助线程仍然处于活动状态,从而导致整个应用程序无法正常退出。这时我们需要一种较安全的方式来结束后台线程的运行,这样我们可以随时结束后台线程的运行,并且在线程结束时进行相应的资源清理工作(例如将内存数据写入硬盘)。.net框架提供了一些工具来实现该功能。 1.IsBackgound属性 Thread类提供了IsBackground属性,当线程的IsBackground属性被设置为true时,表示此线程为后台工作线程。当一个应用程序结束时,它的所有后台线程会自动的被结束执行。如果你有一个后台线程侦听Socket连接,并且正在被阻塞,那么这时候通过设置线程的IsBackground属性为True,使它自动随应用程序的结束而结束是比较合适的。但在这种情况下,线程会静悄悄的结束,它不会引发任何异常,你的线程没有机会执行一些需要的清理代码。例如,内存中的数据可能会来不及写入磁盘,从而造成丢失数据。 2.Abort方法 可以调用Thread类的Abort方法来强制终制线程。上调用此方法时,线程上引发ThreadAbortException,并导至线程终结,通过捕获该异常,可以执行一些资源清理代码。但这种模式也有一些问题,主要是难以知道线程上的代码执行到什么地方,所有相应的资源清理代码也难以编写。总的来说这是一种比较粗暴的终止线程执行的方法,通常来说是不推荐使用的。 3。轮循方式 如果后台线程将执行一个很长的计算,那么可以将计算隔成若干小段,并经常检查是否需要取消线程。.NET框架提供了CancellationTokenSource类来作为线程取消的统一模式。例如:
郑子铭
2023/11/03
2540
如何取消.net后台线程的执行
C# 并行和多线程编程——认识和使用Task
 对于多线程,我们经常使用的是Thread。在我们了解Task之前,如果我们要使用多核的功能可能就会自己来开线程,然而这种线程模型在.net 4.0之后被一种称为基于“任务的编程模型”所冲击,因为task会比thread具有更小的性能开销,不过大家肯定会有疑惑,任务和线程到底有什么区别呢?
用户9127601
2021/11/01
7990
C#多线程和异步(二)——Task和async/await详解
  同步和异步主要用于修饰方法。当一个方法被调用时,调用者需要等待该方法执行完毕并返回才能继续执行,我们称这个方法是同步方法;当一个方法被调用时立即返回,并获取一个线程执行该方法内部的业务,调用者不用等待该方法执行完毕,我们称这个方法为异步方法。
zls365
2021/02/26
7.1K0
.Net多线程编程—任务Task
1 System.Threading.Tasks.Task简介 一个Task表示一个异步操作,Task的创建和执行是独立的。 只读属性: 返回值 名称 说明 object AsyncState 表示在创建任务时传递给该任务的状态数据 TaskCreationOptions CreationOptions 获取用于创建此任务的 TaskCreationOptions CurrentId 当前正在执行 Task 的 ID
甜橙很酸
2018/03/08
1.6K0
Thread、ThreadPool、Task、Parallel、Async和Await基本用法、区别以及弊端
ThreadPool是Thread的一个升级版,ThreadPool是从线程池中获取线程,如果线程池中又空闲的元素,则直接调用,如果没有才会创建,而Thread则是会一直创建新的线程,要知道开启一个线程就算什么事都不做也会消耗大约1m的内存,是非常浪费性能的,接下来我们写一个例子来看一下二者的区别:
AI.NET 极客圈
2019/08/14
1.8K0
C# 中的线程与任务 — 有什么区别?
在C#编程中,类(class)是一种让我们可以同时执行任务的方式,允许我们在程序的其他部分继续运行时执行代码。尽管现代C#开发人员通常使用Task来管理并发性,但Thread类提供了更多的线程行为控制,这使得它在需要进行低级别线程操作时非常有用。
郑子铭
2025/01/07
1130
C# 中的线程与任务 — 有什么区别?
Task 结合 CancellationTokenSource的妙用
在.NET中,CancellationTokenSource、CancellationToken和Task是处理异步操作和取消任务的重要工具。
郑子铭
2025/02/18
820
Task 结合 CancellationTokenSource的妙用
最全C#线程查漏补缺
在单核计算机中,CPU 是独占的,内存是共享的,这时候运行一个程序的时候是没有问题。但是运行多个程序的时候,为了不发生一个程序霸占整个 CPU 不释放的情况(如一个程序死循环无法结束了,那么其他程序就没有机会运行了),就需要开发者给不同程序划分不同的执行时间。为了避免不同程序之间互相操作数据或代码,导致程序被破坏的情况,就需要开发者给程序划分独立的内存范围。也就是程序需要开发者进行调度以及和划分独立的内存空间。
郑子铭
2023/08/30
2680
最全C#线程查漏补缺
C#多线程(14):任务基础②
上一篇,我们学习了任务的基础,学会多种方式场景任务和执行,异步获取返回结果等。上一篇讲述的知识比较多,这一篇只要是代码实践和示例操作。
痴者工良
2021/04/26
7240
C#多线程(12):线程池
线程池全称为托管线程池,线程池受 .NET 通用语言运行时(CLR)管理,线程的生命周期由 CLR 处理,因此我们可以专注于实现任务,而不需要理会线程管理。
痴者工良
2021/04/26
1.5K0
浅谈.Net异步编程的前世今生----TPL篇
我们在此前已经介绍了APM模型和EAP模型,以及它们的优缺点。在EAP模型中,可以实时得知异步操作的进度,以及支持取消操作。但是组合多个异步操作仍需大量工作,编写大量代码方可完成。
独立观察员
2022/12/06
4520
浅谈.Net异步编程的前世今生----TPL篇
C#多线程(13):任务基础①
.NET 中,有三种异步编程模式,分别是基于任务的异步模式(TAP)、基于事件的异步模式(EAP)、异步编程模式(APM)。
痴者工良
2021/04/26
9440
【推荐】C#线程篇---Task(任务)和线程池不得不说的秘密(5.2)
ContinueWith? 啥东西~~??  要写可伸缩的软件,一定不能使你的线程阻塞。这意味着如果调用Wait或者在任务未完成时查询Result属性,极有可能造成线程池创建一个新线程,这增大了资源的消耗,并损害了伸缩性。   ContinueWith便是一个更好的方式,一个任务完成时它可以启动另一个任务。上面的例子不会阻塞任何线程。   当Sum的任务完成时,这个任务会启动另一个任务以显示结果。ContinueWith会返回对新的Task对象的一个引用,所以为了看到结果,我需要调用一下Wait方法,当
逸鹏
2018/04/10
1.6K0
【推荐】C#线程篇---Task(任务)和线程池不得不说的秘密(5.2)
.NET中的异步编程下
2、Task类 Task类是封装的一个任务类,内部使用的是ThreadPool类,提供了内建机制,让你知道什么时候异步完成以及如何获取异步执行的结果,并且还能取消异步执行的任务。下面看一个例子是如何使用Task类来执行异步操作的。 class Program { static void Main(string[] args) { Task t = new Task((c) => {
逸鹏
2018/04/10
9360
[C#] Task.CompletedTask和Task.Result什么时候用?
在学习C#中的Task方法时,可以知道Task启动一个异步线程方法可以用Task.Run()进行,具体可以参看附录部分。
科控物联
2023/09/01
2.2K0
[C#] Task.CompletedTask和Task.Result什么时候用?
C# 多线程六之Task(任务)三之任务工厂
前面两篇关于Task的随笔,C# 多线程五之Task(任务)一 和 C# 多线程六之Task(任务)二,介绍了关于Task的一些基本的用法,以及一些使用的要点,如果都看懂了,本文将介绍另一个Task的特殊用法,前面介绍了,如何通过一个父任务创建多个子任务,且这些子任务都必须要支持取消的例子,常规做法是,通过new 一个Task数组对象,然后在该对象的内部创建多个Task任务,然后给这些任务指定TaskCreationOptions.AttachedToParent,这样所有的子任务都关联到了父任务,接着给这些子任务,绑定一个CancellationToken类实例,当其中一个子任务发生异常时,调用CancellationToken类实例的Cancel方法,将其余的子任务全都取消,大致代码如下:
郑小超.
2018/12/24
9530
c#异步编程-Task(一)
大家好,本次继续分享自己的学习经历。本文主要分享异步编程中Task的使用,如果能帮助大家希望多多关注文章末尾的微信公众号和知乎三连。各位举手之劳是对我更新技术文章最大的支持。
JusterZhu
2022/12/07
7130
C#多线程(15):任务基础③
先说一下 TaskAwaiter,TaskAwaiter 表示等待异步任务完成的对象并为结果提供参数。
痴者工良
2021/04/26
7250
[书籍]用UWP复习《C#并发编程经典实例》
C#并发编程经典实例 是一本关于使用C#进行并发编程的入门参考书,使用“问题-解决方案-讨论”的模式讲解了以下这些概念:
dino.c
2019/01/18
8490
[书籍]用UWP复习《C#并发编程经典实例》
相关推荐
【推荐】C#线程篇---Task(任务)和线程池不得不说的秘密(5.1)
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文