Task 和Thread在效率上有什么区别

OSMeteor 2013-09-22 03:06:37
做异步编程的时候,我发现4.0更新了Task 使用lambad表达式,让语法更精简了。但是具体在执行效率上有什么变化么 ?
...全文
2746 31 打赏 收藏 转发到动态 举报
写回复
用AI写文章
31 条回复
切换为时间正序
请发表友善的回复…
发表回复
qingtianzhuren 2016-04-14
  • 打赏
  • 举报
回复
回复楼上,你可以改默认线程池大小, ThreadPool.SetMaxThreads(2000, 2000); ThreadPool.SetMinThreads(100, 100); 结果线程池还是完败Thread,task也不行。只有设置 很少线程的情况下,线程池和TASK偶尔会启动更快,从效率上讲,微软搞线程池和TASK仿佛是炒THREAD的冷饭
thief3 2015-06-26
  • 打赏
  • 举报
回复
引用 11 楼 sp1234 的回复:
可以写一个测试
using System;
using System.Threading;
using System.Threading.Tasks;

namespace ConsoleApplication1
{
    static class Program
    {
        static void Main(string[] args)
        {
            for (var i = 1; i <= 50; i++)
                TestTask(i);
            for (var i = 1; i <= 50; i++)
                TestThreadPool(i);
            for (var i = 1; i <= 50; i++)
                TestThread(i);
            Console.ReadLine();
        }

        private static void TestThread(int i)
        {
            Console.WriteLine("Thread {0} start.", i);
            new Thread(h =>
            {
                Thread.Sleep(5000);
                Console.WriteLine("-------------------Thread {0} end.", i);
            }).Start();
        }

        private static void TestThreadPool(int i)
        {
            Console.WriteLine("ThreadPool {0} start.", i);
            ThreadPool.QueueUserWorkItem(h =>
              {
                  Thread.Sleep(5000);
                  Console.WriteLine("-------------------ThreadPool {0} end.", i);
              });
        }

        private static void TestTask(int i)
        {
            Console.WriteLine("Task {0} start.", i);
            new Task(() =>
            {
                Thread.Sleep(5000);
                Console.WriteLine("-------------------Task {0} end.", i);
            }).Start();
        }
    }


}
可以看看谁最先打印 ------------------end。 你可以看到,Thread 完胜 Task。
这只是因为Task是用了线程池来控制的,开始的时候线程池内只有默认数量的线程,随着任务增多线程池在增大容量(具体策略不太了解),所以后面几个线程启动晚了。 而Thread是全部一起启动的,所以几乎同时完成。 这是出于稳定性考虑的设计,Task的设计是用来解决实际问题的,比如网络下载、数据读写,瓶颈在于网络或存储的速度,并且要保证稳定。 上面的测试太理论,没有太多实际意义 当然引起思考的作用还是有的...
万德福儿 2015-06-08
  • 打赏
  • 举报
回复
引用 11 楼 sp1234 的回复:
可以写一个测试
using System;
using System.Threading;
using System.Threading.Tasks;

namespace ConsoleApplication1
{
    static class Program
    {
        static void Main(string[] args)
        {
            for (var i = 1; i <= 50; i++)
                TestTask(i);
            for (var i = 1; i <= 50; i++)
                TestThreadPool(i);
            for (var i = 1; i <= 50; i++)
                TestThread(i);
            Console.ReadLine();
        }

        private static void TestThread(int i)
        {
            Console.WriteLine("Thread {0} start.", i);
            new Thread(h =>
            {
                Thread.Sleep(5000);
                Console.WriteLine("-------------------Thread {0} end.", i);
            }).Start();
        }

        private static void TestThreadPool(int i)
        {
            Console.WriteLine("ThreadPool {0} start.", i);
            ThreadPool.QueueUserWorkItem(h =>
              {
                  Thread.Sleep(5000);
                  Console.WriteLine("-------------------ThreadPool {0} end.", i);
              });
        }

        private static void TestTask(int i)
        {
            Console.WriteLine("Task {0} start.", i);
            new Task(() =>
            {
                Thread.Sleep(5000);
                Console.WriteLine("-------------------Task {0} end.", i);
            }).Start();
        }
    }


}
可以看看谁最先打印 ------------------end。 你可以看到,Thread 完胜 Task。
引用 11 楼 sp1234 的回复:
可以写一个测试
using System;
using System.Threading;
using System.Threading.Tasks;

namespace ConsoleApplication1
{
    static class Program
    {
        static void Main(string[] args)
        {
            for (var i = 1; i <= 50; i++)
                TestTask(i);
            for (var i = 1; i <= 50; i++)
                TestThreadPool(i);
            for (var i = 1; i <= 50; i++)
                TestThread(i);
            Console.ReadLine();
        }

        private static void TestThread(int i)
        {
            Console.WriteLine("Thread {0} start.", i);
            new Thread(h =>
            {
                Thread.Sleep(5000);
                Console.WriteLine("-------------------Thread {0} end.", i);
            }).Start();
        }

        private static void TestThreadPool(int i)
        {
            Console.WriteLine("ThreadPool {0} start.", i);
            ThreadPool.QueueUserWorkItem(h =>
              {
                  Thread.Sleep(5000);
                  Console.WriteLine("-------------------ThreadPool {0} end.", i);
              });
        }

        private static void TestTask(int i)
        {
            Console.WriteLine("Task {0} start.", i);
            new Task(() =>
            {
                Thread.Sleep(5000);
                Console.WriteLine("-------------------Task {0} end.", i);
            }).Start();
        }
    }


}
可以看看谁最先打印 ------------------end。 你可以看到,Thread 完胜 Task。
一不小心没看明白,请问这样说明了什么?
OSMeteor 2013-09-25
  • 打赏
  • 举报
回复
引用 27 楼 u011573693 的回复:
TASK注重点在并行~ 所以如果你是工作在多核情况下,那么task或许是你最好的选择了,但是thread却无法实现自动化的并行操作~ task是基于threadPool的,所以相比thread来说,就算再单核,我也依然觉得task这种方式会比thread强~
都得根据电脑的配置来才行 。。。。
1987andy 2013-09-23
  • 打赏
  • 举报
回复
TASK注重点在并行~ 所以如果你是工作在多核情况下,那么task或许是你最好的选择了,但是thread却无法实现自动化的并行操作~ task是基于threadPool的,所以相比thread来说,就算再单核,我也依然觉得task这种方式会比thread强~
blackkettle 2013-09-23
  • 打赏
  • 举报
回复
引用 11 楼 sp1234 的回复:
可以写一个测试
using System;
using System.Threading;
using System.Threading.Tasks;

namespace ConsoleApplication1
{
    static class Program
    {
        static void Main(string[] args)
        {
            for (var i = 1; i <= 50; i++)
                TestTask(i);
            for (var i = 1; i <= 50; i++)
                TestThreadPool(i);
            for (var i = 1; i <= 50; i++)
                TestThread(i);
            Console.ReadLine();
        }

        private static void TestThread(int i)
        {
            Console.WriteLine("Thread {0} start.", i);
            new Thread(h =>
            {
                Thread.Sleep(5000);
                Console.WriteLine("-------------------Thread {0} end.", i);
            }).Start();
        }

        private static void TestThreadPool(int i)
        {
            Console.WriteLine("ThreadPool {0} start.", i);
            ThreadPool.QueueUserWorkItem(h =>
              {
                  Thread.Sleep(5000);
                  Console.WriteLine("-------------------ThreadPool {0} end.", i);
              });
        }

        private static void TestTask(int i)
        {
            Console.WriteLine("Task {0} start.", i);
            new Task(() =>
            {
                Thread.Sleep(5000);
                Console.WriteLine("-------------------Task {0} end.", i);
            }).Start();
        }
    }


}
可以看看谁最先打印 ------------------end。 你可以看到,Thread 完胜 Task。
+1
chen870201 2013-09-23
  • 打赏
  • 举报
回复
前来学习了
hudsonhuang 2013-09-22
  • 打赏
  • 举报
回复
引用 21 楼 sp1234 的回复:
[quote=引用 19 楼 hudsonhuang 的回复:] 本来一个东西,要用多线程来实现的 在编译的时候,就把多线程改成单线程了(看了一下,其实就是加了一下while的跳转)
什么叫做“改成单线程”?[/quote] 本来要多线程实现的 现在我们只需要单线程就能实现了 -_-
hudsonhuang 2013-09-22
  • 打赏
  • 举报
回复
引用 20 楼 sp1234 的回复:
[quote=引用 16 楼 hudsonhuang 的回复:] 线程之间切换是要耗费时间的,所以并不是越多线程越好的 网上找了一下,最优的是cpu核数*2(也有人说cpu*2+2) 合理的减少线程数可以提高程序的运行速度 其他的,请直接google .net 4.5新特性/await、async
在电脑有很多工作、要等待各种各样的外设的时候,只有 CPU数*2 个线程够干什么? 你所说的那种,是指电脑闲的没事干的时候的结论。也就是说当你的线程数刚刚超出CPU个数时你的CPU占用率就接近100%的情况。 然后看看你的windows的进程管理器的读数,在一个双核电脑上当前系统可能已经用了1500个线程,你认为windows的开发者是因为不知道你规定的“cpu核数*2”的公式而出现bug了吗? [/quote]
引用 20 楼 sp1234 的回复:
[quote=引用 16 楼 hudsonhuang 的回复:] 线程之间切换是要耗费时间的,所以并不是越多线程越好的 网上找了一下,最优的是cpu核数*2(也有人说cpu*2+2) 合理的减少线程数可以提高程序的运行速度 其他的,请直接google .net 4.5新特性/await、async
在电脑有很多工作、要等待各种各样的外设的时候,只有 CPU数*2 个线程够干什么? 你所说的那种,是指电脑闲的没事干的时候的结论。也就是说当你的线程数刚刚超出CPU个数时你的CPU占用率就接近100%的情况。 然后看看你的windows的进程管理器的读数,在一个双核电脑上当前系统可能已经用了1500个线程,你认为windows的开发者是因为不知道你规定的“cpu核数*2”的公式而出现bug了吗? [/quote] 哦,网上就是这么说的,要比你找个公认的说法给我看看 另外你觉得线程转换耗费的时间真的可以不计算么? 另外,我举这个只是想说明,减少线程可以提高速度而已 你想bug去吧。。。
  • 打赏
  • 举报
回复
引用 19 楼 hudsonhuang 的回复:
本来一个东西,要用多线程来实现的 在编译的时候,就把多线程改成单线程了(看了一下,其实就是加了一下while的跳转)
什么叫做“改成单线程”?
  • 打赏
  • 举报
回复
引用 16 楼 hudsonhuang 的回复:
线程之间切换是要耗费时间的,所以并不是越多线程越好的 网上找了一下,最优的是cpu核数*2(也有人说cpu*2+2) 合理的减少线程数可以提高程序的运行速度 其他的,请直接google .net 4.5新特性/await、async
在电脑有很多工作、要等待各种各样的外设的时候,只有 CPU数*2 个线程够干什么? 你所说的那种,是指电脑闲的没事干的时候的结论。也就是说当你的线程数刚刚超出CPU个数时你的CPU占用率就接近100%的情况。 然后看看你的windows的进程管理器的读数,在一个双核电脑上当前系统可能已经用了1500个线程,你认为windows的开发者是因为不知道你规定的“cpu核数*2”的公式而出现bug了吗?
hudsonhuang 2013-09-22
  • 打赏
  • 举报
回复
引用 18 楼 sp1234 的回复:
[quote=引用 12 楼 hudsonhuang 的回复:] 直接在编译的时候,把多线程的实现改成单线程实现去了,小伙们都惊呆了。。。
晕死!什么叫做“把多线程的实现改成单线程实现”? [/quote] 本来一个东西,要用多线程来实现的 在编译的时候,就把多线程改成单线程了(看了一下,其实就是加了一下while的跳转)
  • 打赏
  • 举报
回复
引用 12 楼 hudsonhuang 的回复:
直接在编译的时候,把多线程的实现改成单线程实现去了,小伙们都惊呆了。。。
晕死!什么叫做“把多线程的实现改成单线程实现”?
OSMeteor 2013-09-22
  • 打赏
  • 举报
回复
http://developer.51cto.com/art/201305/393992_1.htm 好吧 我贴出来了 5.0 的特性
hudsonhuang 2013-09-22
  • 打赏
  • 举报
回复
引用 15 楼 kllxyu 的回复:
可以发个链接在这里不?让大家都了解了解。。。
-_- 线程之间切换是要耗费时间的,所以并不是越多线程越好的 网上找了一下,最优的是cpu核数*2(也有人说cpu*2+2) 合理的减少线程数可以提高程序的运行速度 其他的,请直接google .net 4.5新特性/await、async
OSMeteor 2013-09-22
  • 打赏
  • 举报
回复
引用 12 楼 hudsonhuang 的回复:
[quote=引用 10 楼 kllxyu 的回复:] [quote=引用 8 楼 hudsonhuang 的回复:] 刚看了一下,学习了 task类似于轻量级的线程池,但是比线程池多了一些有点,比如是状态之类的 另外想问问楼主,有什么实际的情况,要用到这些呢?因为我更偏向于多线程实现。。
我主要用于扫描程序这方面。我之前用多线程不理想,所以就发帖问了。还有监控程序用多线程也用的很多的 [/quote] 看看4.5的特性吧,await,据说这个东西出来之后JAVA怎么追都追不上.NET了。。。 直接在编译的时候,把多线程的实现改成单线程实现去了,小伙们都惊呆了。。。[/quote]可以发个链接在这里不?让大家都了解了解。。。
OSMeteor 2013-09-22
  • 打赏
  • 举报
回复
结贴了,这是我测试的结果,我电脑的i5处理器,对一般的电脑建议用Thread 配置好点的可以用Task 感谢各位同学的热心帮助。
gunziyang 2013-09-22
  • 打赏
  • 举报
回复
好贴,学习了
hudsonhuang 2013-09-22
  • 打赏
  • 举报
回复
引用 10 楼 kllxyu 的回复:
[quote=引用 8 楼 hudsonhuang 的回复:] 刚看了一下,学习了 task类似于轻量级的线程池,但是比线程池多了一些有点,比如是状态之类的 另外想问问楼主,有什么实际的情况,要用到这些呢?因为我更偏向于多线程实现。。
我主要用于扫描程序这方面。我之前用多线程不理想,所以就发帖问了。还有监控程序用多线程也用的很多的 [/quote] 看看4.5的特性吧,await,据说这个东西出来之后JAVA怎么追都追不上.NET了。。。 直接在编译的时候,把多线程的实现改成单线程实现去了,小伙们都惊呆了。。。
  • 打赏
  • 举报
回复
可以写一个测试
using System;
using System.Threading;
using System.Threading.Tasks;

namespace ConsoleApplication1
{
    static class Program
    {
        static void Main(string[] args)
        {
            for (var i = 1; i <= 50; i++)
                TestTask(i);
            for (var i = 1; i <= 50; i++)
                TestThreadPool(i);
            for (var i = 1; i <= 50; i++)
                TestThread(i);
            Console.ReadLine();
        }

        private static void TestThread(int i)
        {
            Console.WriteLine("Thread {0} start.", i);
            new Thread(h =>
            {
                Thread.Sleep(5000);
                Console.WriteLine("-------------------Thread {0} end.", i);
            }).Start();
        }

        private static void TestThreadPool(int i)
        {
            Console.WriteLine("ThreadPool {0} start.", i);
            ThreadPool.QueueUserWorkItem(h =>
              {
                  Thread.Sleep(5000);
                  Console.WriteLine("-------------------ThreadPool {0} end.", i);
              });
        }

        private static void TestTask(int i)
        {
            Console.WriteLine("Task {0} start.", i);
            new Task(() =>
            {
                Thread.Sleep(5000);
                Console.WriteLine("-------------------Task {0} end.", i);
            }).Start();
        }
    }


}
可以看看谁最先打印 ------------------end。 你可以看到,Thread 完胜 Task。
加载更多回复(10)

110,571

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧