线程是否比任务运行得更快?
仅通过将一行代码替换为使用任务的线程,我的应用程序的速度就提高了。
因此,我决定进行如下小实验:
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/