向任务发送消息
本文关键字:消息 任务 | 更新日期: 2023-09-27 18:32:31
我正在编写一个程序,根据用户提供的某些条件显示曼德布洛特集。由于计算时间很长(超过 500 毫秒(,我决定使用多个线程。在没有任何经验的情况下,我设法通过使用System.Threading.Tasks类来做到这一点,该类工作得很好。我唯一不喜欢的是,每次生成曼德布洛特时,都会创建线程,然后销毁。
这是它如何工作的一个例子。每次调用该方法时,它都会创建线程(任务(。
for (int i = 0; i < maxThreads; i++) {
int a = i;
tasks[a] = Task.Factory.StartNew(() => generateSector(a));
}
我不知道这如何影响性能,但看起来创建和销毁线程是昂贵的时间,并且让线程准备好并等待触发消息会更有效,当它们完成后回到等待状态。可能以下示例代码有助于理解这个想法。
for (int i = 0; i < maxThreads; i++)
tasks[i].sendMessage("Start"); // Tells the running thread to begin its work
因此,每个线程都会执行一个无限循环,在该循环中,它一直等待到需要它们进行计算。然后,它将继续等待。像这样:
// Into the method that a thread executes
while(true) {
Wait(); // Waits for the start signal
calculate(); // Do some calculations
} // Go back to waiting
那会更有效率吗?有什么办法可以做到这一点吗?
保持代码不变。
1(任务使用线程池线程,所以没有问题
2("我不知道这如何影响性能"——这是你应该开始的地方。切勿在测量前进行优化。您是否有性能问题?您的代码运行缓慢吗?我想不会,所以你不应该被打扰。
当你使用 Task.Factory.StartNew(...)
时,你不一定是在创建和销毁线程。任务库使用ThreadPool
来执行此操作,因此您不需要自己管理它,就像您自己创建new Thread()
一样。
听起来您正在尝试使用一组线程并设置一个系统来调度在这些线程上运行的工作。这是一个好主意,但事实上,它是如此伟大的想法,它内置到 .NET 框架中,你不需要自己构建它。这实际上正是任务的目的。
任务是线程池上相对轻量级的抽象,由 .NET 运行时管理。线程是一种相对较重的操作系统构造,在线程之间启动、停止和上下文切换的成本有些高。创建任务时,它会计划该任务在池中的下一个可用线程上执行,.NET 运行时将根据是否有工作排队并等待线程执行,自动增加和减少池的大小。如果需要,您可以自定义最小和最大线程数,但通常这不是必需的。
因此,通过简单地创建在单个工作单元的生存期内存在的短期任务,他们已经可以让你的工作在实际线程的托管集合上运行。