C# 多线程之Task(任务

本文探讨了C#中Task的引入原因,分析了Task与Thread、ThreadPool的区别,指出了Task的性能损耗,并通过实战示例展示了如何创建、取消任务,以及使用ContinueWith方法。Task在提升开发效率的同时,也可能带来性能下降,需要权衡使用。
摘要由CSDN通过智能技术生成

C# 多线程之Task(任务

 

 

1、简介

为什么MS要推出Task,而不推Thread和ThreadPool,以下是我的见解:

(1)、Thread的Api并不靠谱,甚至MS自己都不推荐,原因,它将整个Thread类都不开放给Windows Sotre程序,且它的Api过于强大,如果在程序中过度使用,维护的成本太高,想想代码中充斥着挂起线程,阻塞线程、后期的应用程序很难维护.

(2)、ThreadPool最大的问题是,所有的辅助线程都是异步的,没有向Thread的Join方法那样去等待一个线程执行完,然后执行回调函数的机制,也就是你无法判断线程什么时候执行完,也没有机制获得线程的返回值,所有MS推出了Task来解决Thread和ThreadPool的问题

当然最主要的是,Thread和Thread好用.因为Task是它们的升级版,升级版当然比较好.

 

2、Task的缺点

虽然Task以其强大的Api,以及封装,让我们在CLR环境下,能完成高效率的编程,但是它并不是没有缺点的,高效率的背后,肯定带来的性能的损失,这一点很多类似的框架都能说明,比如EF,强大的背后,大量的使用了反射等操作,所以虽然开发效率提升了,但是性能却下降了,这里不想说太多,所以简单的api可能不会产生过多的性能损耗,所以这也是为什么大型互联网项目,更愿意使用原生Ado或者Dapper去做.所以这些在我们的实际开发中,这些都需要我们去权衡.有得必有失.下面来简单的说下Task具体在哪里会产生性能损失:

 很直观,直接分析ThreadPool类和Task类的构造:

ThreadPool类

很简洁,没有任何的字段和属性!

Task类,1700行代码,里面有大量的字段和属性,大致如下:

还包括对父任务的引用、任务调度器(TaskScheduler)的引用、对回调方法的引用、对执行上下文(ExecutionContext)的引用、对ManualResetEventSlim信号量的引用、还有CancellationToken取消信号量(我把它理解为信号量)的引用、一个ContinueWithTask的任务集合的引用、还有未抛出异常的Task对象集合的引用等等,这些后面的文章都会介绍.

所以,不分析具体的性能损耗点,但是单单两个类的构造,你就能清楚使用那个类创建线程所产生的性能消耗大.

 

3、实战

(1)、不带返回值,实现和ThreadPool线程池线程一样的效果

复制代码
        static void Main(string[] args) 
        {
            var result=Task.Run(() => Calculate("这个参数很六啊"));
            Console.WriteLine("主线程有没有在继续执行,look look");
            Console.ReadKey();
        }

        static void Calculate(string param)
        {
            Console.WriteLine("子线程开始执行,带着主线程给它传递的参数呢!参数是:{0}",param);
            Thread.Sleep(2000);
            Console.WriteLine("子线程执行完了");
        }
复制代码

根据输出,发现主线程并没有等带子线程执行完毕,通过开启一个新线程之后,立刻返回去执行它自己的任务.

 

(2)、带返回值

复制代码
        static void Main(string[] args) 
        {
            var result=Task.Run(() => Calculate(1));
            Console.WriteLine(result.Result);
            Console.WriteLine("主线程有没有在继续执行,look look");
            Console.ReadKey();
        }

        /// <summary>
        /// 简单递归计算n+(n-1)+.....+1
        /// </summary>
        /// <param name="param"></param>
        /// <returns></returns>
        static int Calculate(int param)
        {
            if (param &#
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值