【问题标题】:Task creating another Task任务创建另一个任务
【发布时间】:2015-07-09 04:33:18
【问题描述】:
for (int i = 0; i < someNumber; i++)
{
    Task<myObject>.Run(() => 
    {
       // some work
       // ...
       Task<myObjectNew>.Run(() => { // other work });
    });
}

我有一个循环,它创建了许多初始任务(最多 100 个)。然后这些任务中的每一个都做一些小的工作单元,然后自己创建另一个任务。我注意到的是,最初的 100 个任务在全部设置完成之前都不会启动。

如果初始任务创建了一个线程而不是另一个任务,那么一切似乎都很好,一旦创建了第一个外部任务,它就会开始执行(并产生一个新线程等)。

我没有看到像以前那样的行为,但我又没有让一个任务创建另一个任务。

有什么想法吗?

【问题讨论】:

  • 如果您只是调用 Task.Run 并想立即开始,使用 TPL 似乎只会增加不必要的开销和混乱;您是否考虑过保持简单并只需致电new Thread(...).Start()
  • @DaxFohl 你能解释一下它是如何引入开销的吗?
  • 也许试图解释你的最终目标是什么。有很多抽象(例如TPL Dataflow)可以帮助您进行线程调度,而不是自行推出。
  • @Science_Fiction,您可能想尝试调整ThreadPoolThreadPool.SetMaxThreads(200, 200); ThreadPool.SetMinThreads(100, 100); 尽管正如其他人所说,可能有比您使用的更好的方法。
  • @yuri task 是线程之上的一个层,那怎么不呢?

标签: c# .net multithreading task-parallel-library


【解决方案1】:

Task&lt;T&gt; 对象通过线程池进行管理,并且在启动速度方面受到限制。我不记得当前的默认设置,但基本的想法是一旦线程池中的线程用完,新线程只会以每秒一个(左右)的速度创建。

当您显式创建Thread 对象时,无需等待。它们立即创建并开始。在线程真正开始执行之前,可能会有几十毫秒的轻微延迟,否则它实际上是瞬时的。

【讨论】:

  • 确实应该至少开始一些早期任务吗?
  • 缺乏可靠地重现行为的a good, minimal, complete code example,因此无法确定发生了什么。我只是在解释次要任务/线程之间的区别。在我看来,no 主要任务在全部设置完成之前就开始了,因为如果是这种情况,那么这些任务的方法的 content 不会影响启动行为。
【解决方案2】:

使用线程池工作线程调度任务。 如果您想绕过线程池,您可以将您的任务声明为LongRunning,这将立即启动一个新线程。

如果您需要有关它的更多信息: https://msdn.microsoft.com/en-us/library/ff963549.aspx

【讨论】:

    猜你喜欢
    • 2021-04-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多