StartNew是否在呼叫期间保持一个线程?

时间:2012-04-16 17:13:43

标签: .net asynchronous threadpool task-parallel-library

我假设StartNew在实际工作时只使用了ThreadPool中的一个线程,并在等待时释放它。例如:

    Task.Factory.Startnew() {
          () => {
                    ..
                    var dr = cmd.ExecuteReader();
                    while (dr.Read())
                    {
                     ..
                    }
                }
}

所以说上面的cmd.ExecuteReader()是一个非常慢的存储过程,需要10分钟才能运行。我以为TPL会将线程释放回池中而不是一直保持线程。这是不正确的?如果不是TPL approcach说一个后台工作者线程的大优势是什么。在阅读Stephen Toub's post之后,我开始认为我的假设不正确。

1 个答案:

答案 0 :(得分:2)

不,这不是线程在.Net中的工作方式。如果你进行阻塞调用,线程必须实际阻塞,它不能做任何其他事情。 TPL中没有“神奇”可以做到这一点。*

基本上,调用ThreadPool.QueueUserWorkItem()Task.Factory.StartNew()之间没有太大区别。但使用TPL有许多优点,例如:

  1. 支持取消。
  2. 支持续约(task.ContinueWith())。
  3. 支持线程池以外的其他调度程序。最常用的是同步上下文,在GUI应用程序中很有用。
  4. 内联任务(如果您开始等待尚未启动的任务,它可以开始在当前线程上执行)。
  5. 任务的线程局部队列,可以提高性能。
  6. Task是对将来完成的事物的单一抽象,它不一定是计算绑定的后台操作。这在.Net 4.5中将变得更加重要。
  7. * C#5具有编译器魔力,可以使您的异步代码看起来像今天的同步代码。但阻止通话仍然会阻止通话。