【问题标题】:Threadpool design question线程池设计问题
【发布时间】:2010-06-15 00:08:08
【问题描述】:

我有一个设计问题。我想要一些反馈来了解 ThreadPool 是否适合我正在编写的客户端程序。

我有一个客户端作为处理数据库记录的服务运行。这些记录中的每一个都包含与外部 FTP 站点的连接信息[基本上它是一个要传输的文件队列]。其中很多都在同一个主机上,只是移动不同的文件。因此,我按主机将它们分组在一起。我希望能够为每个主机创建一个新线程。我真的不在乎转移何时完成,他们只需要完成分配给他们的所有工作(或尝试做),然后在完成后终止,清理他们在此过程中使用的所有资源。

我预计建立的连接不会超过 10-25 个。一旦传输队列为空,程序将简单地等待,直到队列中再次有记录。

ThreadPool 是一个很好的候选者还是我应该使用不同的方法?

编辑:在大多数情况下,这是在服务器上运行的唯一重要的自定义应用程序。

【问题讨论】:

    标签: c# multithreading threadpool


    【解决方案1】:

    不,线程池不合适。线程池实际上是为“需要后台处理的短任务”而设计的,因为框架依赖于线程池线程的可用性,而长时间运行的进程可能会耗尽线程池。

    Ftp 传输需要相对较长的时间(即使有合理的超时时间),因此它们并不适合。您也许可以通过使用线程池获得,但如果您使用它,您也可能会发现自己遇到了莫名其妙的错误。这取决于您的应用程序使用线程池相关框架功能(异步委托等)的程度。

    MSDN 主题“The Managed Thread Pool”为何时使用线程池线程提供了很好的指导:

    有几种情况适合创建和管理自己的线程而不是使用线程池线程:

    • 您需要一个前台线程。
    • 您需要线程具有特定的优先级。
    • 您的任务会导致线程长时间阻塞。这 线程池的最大数量 线程,所以大量阻塞 线程池线程可能会阻止 任务从头开始。
    • 您需要将线程放入单线程单元中。全部 ThreadPool 线程在 多线程单元。
    • 您需要有一个与线程关联的稳定身份,或者 将线程专用于某项任务。

    【讨论】:

    • 感谢您的意见。您是否建议我只创建线程并自己管理它们?
    • 确实,从长远来看,创建线程并自己管理它们是必经之路。与 FTP 传输时间相比,启动线程的成本微不足道,这说明了线程池的主要好处之一(另一个是简化的接口 QueueUserWorkItem 提供)。
    【解决方案2】:

    根据您的描述,听起来线程池很合适。

    问题:

    1. 线程池线程不会让您的进程在关闭时保持活动状态。确保这是您想要的行为。

    2. 在较早的阅读中,当应用程序可能正在等待不匹配的连接(如 Web 应用程序)时,将线程池与长时间运行的任务捆绑在一起可能很糟糕。但是,听起来您正在运行一个专用的 Windows 服务,所以我认为这不是问题。

    3. 仅仅因为您在线程池中抛出 10 个作业并不意味着它会立即分派 10 个线程来完成工作——您将使用多少线程的决定委托给 .net 和 o/ s.

    【讨论】:

    • +1 同意你的所有推理,线程池非常适合。
    【解决方案3】:

    ThreadPool 会很好,因为它允许您专注于设置排队到线程的作业,而不用担心初始化和清理单个线程。

    但是您希望它如何工作?您是要将多个作业排队到主机的池中,还是要为每个主机设置一个线程,从其自己的队列中读取作业?

    【讨论】:

    • 队列只有一个数据库表,机器名有一列。客户端服务将通过它自己的机器名称进行查询。然后,从该记录子集(假设返回 100 条记录)中,它将按主机分组(假设它从 100 条记录的集合中返回 4 个唯一主机)。所以,我想在池中为每个主机启动 4 个线程。
    猜你喜欢
    • 1970-01-01
    • 2020-10-02
    • 1970-01-01
    • 2011-02-27
    • 1970-01-01
    • 2017-07-08
    • 2011-09-03
    • 2018-09-23
    相关资源
    最近更新 更多