c# - 线程比任务运行得更快吗?

标签 c# multithreading task

线程是否比任务运行得更快?

仅通过将一行代码替换为使用任务的线程,我的应用程序的速度就提高了。

因此,我决定进行如下小实验:

using System.Diagnostics;

void LongRunning()
{
    Thread.Sleep(3000);
}
Stopwatch s1 = new Stopwatch();
TimeSpan ts;
string elapsedTime;

//thread----------------------
s1.Reset();
s1.Start();
var threadList = new List<Thread>();
for (int i = 0; i < 100; i++)
{
    Thread t = new Thread(LongRunning);
    threadList.Add(t);
    t.Start();
}

foreach (var th in threadList)
{
    th.Join();
}

s1.Stop();
ts = s1.Elapsed;
elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}",
    ts.Hours, ts.Minutes, ts.Seconds,
    ts.Milliseconds / 10);
Console.WriteLine("RunTime Thread " + elapsedTime);


//task----------------------
s1.Reset();
s1.Start();
var taskList = new List<Task>();
for (int i = 0; i < 100; i++)
    taskList.Add(Task.Factory.StartNew(LongRunning));


Task.WaitAll(taskList.ToArray());
s1.Stop();
ts = s1.Elapsed;
elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}",
   ts.Hours, ts.Minutes, ts.Seconds,
   ts.Milliseconds / 10);
Console.WriteLine("RunTime Task " + elapsedTime);
Console.ReadLine();

使用任务,大约需要 25 秒,而使用线程,只需大约 4 秒

最佳答案

这一行:

Task.Factory.StartNew(LongRunning);

安排 LongRunning 在线程池线程上运行。 Thread pool是一组可重用的线程,它有管理这组线程的逻辑。当您尝试将一些工作安排到池中并且它没有可用的空闲线程时 - 它不需要立即生成新线程。它可能会稍等片刻,看看一些当前繁忙的线程是否很快就会可用。

因此,长时间阻塞线程池线程并不是一个好主意,但这正是您在此示例中所做的 - 您使用 Thread.Sleep(3000) 阻塞线程池线程 3 秒)。循环的前几次迭代采用所有可用的线程池线程,然后在每次下一次迭代中,线程池稍等片刻,看看是否有一个现有线程可用。如果不是这样,它会向池中添加一个新线程并在其上运行您的工作。

线程池的这种等待是您的“任务”代码需要更多时间才能完成的原因。

如果你打算执行长阻塞操作,你可以使用:

Task.Factory.StartNew(LongRunning, TaskCreationOptions.LongRunning);

关于c# - 线程比任务运行得更快吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74623661/

相关文章:

c# - 似乎无法以父形式将 mdichild 居中

C - exec 是否必须在多线程进程中立即跟随 fork?

java - 执行某些操作时停止应用程序

c# - 如何处理匿名任务的异常?

c# - 设置用户控件的默认事件

c# - 指示方法仅在匿名事件处理程序完成后返回

c# - WPF 设置窗口数据上下文

c++ - 线程构建 block 流程图——创建一个 "counting"节点

multithreading - 在 Delphi 中,读取 TList<x> 线程安全吗?

java - 将 Eclipse 中的 "Tasks"范围缩小到 TODO、FIXME 等的单一路径