【问题标题】:Does the StartNew hold a thread for the duration of a call?StartNew 在通话期间是否持有一个线程?
【发布时间】:2012-04-28 01:06:57
【问题描述】:

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

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

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

【问题讨论】:

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


    【解决方案1】:

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

    基本上,调用ThreadPool.QueueUserWorkItem()Task.Factory.StartNew() 并没有太大区别。但是使用 TPL 有很多优点,比如:

    1. 支持取消。
    2. 支持延续 (task.ContinueWith())。
    3. 支持线程池以外的其他调度程序。最常用的一种是同步上下文,在 GUI 应用程序中很有用。
    4. 内联任务(如果您开始等待尚未启动的任务,它可以开始在当前线程上执行)。
    5. 任务的线程本地队列,可以提高性能。
    6. Task 是对将来完成的事物的单一抽象,它不必是计算绑定的后台操作。这在 .Net 4.5 中将变得更加重要。

    * C# 5 具有编译器的魔力,可以让您的异步代码看起来像今天的同步代码。但阻塞调用仍将保持阻塞调用。

    【讨论】:

    • 谢谢,我想我对调用 asp.net 异步操作和调用一些使用 IO 完成端口的函数感到困惑,该端口允许您将线程释放回池
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多