Task使用&线程等待&延续

什么是Task?


Task是用来实现多线程的类,在以前当版本中已经有了Thread及ThreadPool,为什么还要提出Task类呢,这是因为直接操作Thread及ThreadPool,向线程中传递参数,获取线程的返回值及线程当启停时都非常的麻烦,所以微软的工程师对Thread进行了再封装,这就是Task,可以这么说Task是架构在Thread之上的,所以多线程时Task是我们的首选。

任务的线程是后台线程。

本质上讲,任务就是一个线程池的增强版API 。

线程池的缺点


1、线程池获取结果并不方便

2、异步处理不方便

3、连续的异步操作不方便

目的:


场景1:  3个并发请求,通过3个接口获取数据,我们希望得到所有接口的数据进行下一步业务处理。

场景2:  3个并发请求,只要其中某一个完成了,就触发一个事件结果。
 

Task的声明

Task的声明有两种方式:

a.通过new 的方式来声明

 Task obj = new Task();

b.通过Task.Factory.StartNew的方式来声明

Task.Factory.StartNew(MyMethod);

获取任务返回值


Task<string> task = new Task<string>(() =>
{
    DoSomething();
    return "此处为执行完成的结果";
});
task.Start();
Console.WriteLine(task.Result);


任务的回调


task.ContinueWith

(1)支持1个 task 接多个ContinueWith

(2)ContinueWith返回下一代 task,下一代可以继续ContinueWith,类似于Lambda

Task<string> task = new Task<string>(() =>
{
     Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
     return "boy,";
});
task.ContinueWith((t) =>
{
     Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
     Console.WriteLine(t.Result + "come on.");
});
task.Start();
Console.ReadLine();


Task的线程等待和延续

Wait
针对单个Task的实例,可以让某一个线程进入等待。

WaitAny
执行的所有线程中只要有一个线程结束,主线程就执行,否则就卡住。

WatiAll
表示任务列表中所有的任务都已经结束后,主线程恢复。

WhenAny
表示任务列表中任何一个任务结束后,配合ContinueWith进行回调触发。

WhenAll
表示任务列表中所有任务都结束后,配合ContinueWith进行回调触发。

注意:WhenAny和WhenAll,都是开启一个新线程执行,不卡顿主线程。

TaskFactory
TaskFactory可以开启线程,当然也对应线程的等待和延续。

ContinueWhenAny:等价于Task的WhenAny+ContinueWith

ContinueWhenAll:等价于Task的WhenAll+ContinueWith

using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
 
namespace ConsoleApp1
{
    class Program
    {
        public static void Main(string[] args)
        {
            List<Task<string>> taskList = new List<Task<string>>();
            Task<string> t1 = new Task<string>(() =>
            {
                return GetName();
            });
            Task<string> t2 = new Task<string>(() =>
            {
                return GetMongo();
            });
            taskList.Add(t1);
            taskList.Add(t2);
            t1.Start();
            t2.Start();            
            Task.WhenAll(taskList.ToArray()).ContinueWith(x =>
            {
                Console.WriteLine("任务执行完毕");
                Console.WriteLine(x.Result[0]);
                Console.WriteLine(x.Result[1]);
            });
            Console.ReadLine();
        }
        public static string GetName()
        {
            Thread.Sleep(5000);
            return "MSSQL";
        }
        public static string GetMongo()
        {
            Thread.Sleep(10000);
            return "MongoDB";
        }
    }
}

Task直接进行线程同步 Tasl.WaitAll() (相当于AutoResetEvent

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值