gpt4 book ai didi

c# - 多任务变慢

转载 作者:可可西里 更新时间:2023-11-01 02:59:41 32 4
gpt4 key购买 nike

代码:

static void DoIt(string name)
{
Console.WriteLine("Hello {0} | {1}", name, Thread.CurrentThread.ManagedThreadID);
Thread.Sleep(5000);
Console.WriteLine("Bye {0} | {1}", name, Thread.CurrentThread.ManagedThreadID);
}

static void Main()
{
Task.Factory.StartNew(() => DoIt("One"));
Task.Factory.StartNew(() => DoIt("Two"));
Task.Factory.StartNew(() => DoIt("Three"));
Task.Factory.StartNew(() => DoIt("Four"));
Task.Factory.StartNew(() => DoIt("Five"));
Task.Factory.StartNew(() => DoIt("Six"));
Task.Factory.StartNew(() => DoIt("Seven"));
Task.Factory.StartNew(() => DoIt("Eight"));
Task.Factory.StartNew(() => DoIt("Nine"));
Task.Factory.StartNew(() => DoIt("Ten"));

Console.ReadKey();
}

为什么它可以很好地立即启动前 3 个任务,但随后需要 5-10 秒才能启动任务 4,而在任务 4 启动后,又需要 5-10 秒才能启动任务 5,依此类推。是 GC 正在做某事吗?有人可以澄清发生了什么吗?

最佳答案

How come that it can fine start the first 3 Tasks immediately, but then it takes 5-10sec for Task 4 to start, and after Task 4 have started, then it takes 5-10sec before Task 5 starts and so on. Is it the GC thats doing something? Could someone please clarify whats happening?

默认情况下,第一次运行时,ThreadPool 使用最少数量的工作线程进行分配。在安排前 4 个任务后,线程池将“加速”以随着时间的推移处理更多任务,这就是您看到延迟的原因。

在我的系统(有 8 个内核)上,前 8 个是瞬时的,然后接下来的两个在一秒后启动。

在您的情况下,如果您运行测试两次,第二次,所有线程都将立即启动。这是因为,在第一次运行之后,ThreadPool 应该有足够的工作线程来立即安排它。

尝试以下操作以查看此行为的实际效果。如果您保留 SetMinThreads 调用,这些将立即安排。如果您将其注释掉,您会发现,第一次需要一段时间,但第二次(假设您等待线程完成),线程将立即运行。

static void DoIt(string name)
{
Console.WriteLine("Hello {0} | {1} - {2}", name, Thread.CurrentThread.ManagedThreadId, DateTime.Now);
Thread.Sleep(5000);
Console.WriteLine("Bye {0} | {1} - {2}", name, Thread.CurrentThread.ManagedThreadId, DateTime.Now);
}

static void Main()
{
int workerThreads, complete;
ThreadPool.GetMinThreads(out workerThreads, out complete);

Console.WriteLine(workerThreads);

// Comment out this line to see the difference...
// WIth this commented out, the second iteration will be immediate
ThreadPool.SetMinThreads(100, complete);

Action run = () =>
{
for (int i = 0; i < 20; ++i)
{
int tmp = i;
Task.Factory.StartNew(() => DoIt(tmp.ToString()));
}
};

run();
Console.WriteLine("Press a key to run again...");
Console.ReadKey();

run();

Console.WriteLine("Press a key to exit...");
Console.ReadKey();
}

请注意,此行为实际上与整个 TPL 几乎没有关系 - 它更像是默认使用的 TaskScheduler,它只是将任务传递给 ThreadPool。例如,如果您在 StartNew() 调用中使用 LongRunning 提示设置这些线程,它们都会立即启动(因为默认调度程序将设置一个新的专用线程并立即执行)。

关于c# - 多任务变慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7393938/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com