【发布时间】:2019-03-25 15:35:03
【问题描述】:
我试图了解使用常见的Threads 和Tasks 之间的好处。第一个进入System.Threading 命名空间,后者进入System.Threading.Tasks 命名空间。
所以,只是为了玩和熟悉它们,我在C#写了这个程序:
class Program
{
static void Main(string[] args)
{
long ticksAtStart = DateTime.UtcNow.Ticks;
new Thread(() => { ExecuteAsyn("Thread", DateTime.UtcNow.Ticks); }).Start();
Console.WriteLine("Using Thread: " + (DateTime.UtcNow.Ticks - ticksAtStart));
ticksAtStart = DateTime.UtcNow.Ticks;
Task g = Task.Factory.StartNew(() => ExecuteAsyn("TPL", DateTime.UtcNow.Ticks));
Console.WriteLine("Using TPL: " + (DateTime.UtcNow.Ticks - ticksAtStart));
g.Wait();
Console.ReadKey();
}
private static void ExecuteAsyn(string source, long ticksAtExecutionTime)
{
Console.WriteLine("Hello World! Using " + source + " the difference between initialization and execution is " + (DateTime.UtcNow.Ticks - ticksAtExecutionTime));
}
}
因此,根据我的理解,任务应该更高效,因为它们使用 ThreadPool 中可用的线程,而创建和启动新线程可能非常消耗资源。
该程序记录两个事件。 CRL 需要两次创建两种对象的滴答数,以及创建线程和实际执行所提供委托之间的滴答声,在我的情况下为 ExecuteAsync。
我没想到的事情发生了:
使用线程:11372 Hello World!使用 Thread 的区别 初始化和执行是 5482 使用 TPL: 333004 Hello World! 使用 TPL 初始化和执行之间的差异是 0
因此,使用经典线程似乎比使用任务更高效。 但对我来说,这里有些奇怪。谁能启发我这个话题? 谢谢。
【问题讨论】:
-
取决于你真正想要做什么,如果你正在创建一个
Console.WritelineHello world 应用程序,它启动一个thread和一个task,你可能是对的,你已经找到了你的赢家。 -
使用
Stopwatch类来做你的计时;DateTime对此毫无用处。 -
如果您正在创建一个需要重用线程池和完成端口监控并发性的线程的服务器,需要一个调度程序,它具有丰富的任务集功能,我怀疑它会比较
标签: c# multithreading task threadpool