【问题标题】:Question regarding threading/background workers关于线程/后台工作者的问题
【发布时间】:2011-03-28 18:23:09
【问题描述】:

我有一个关于线程和后台工作人员的问题,希望您能提供帮助。

我计划制作一个 ftp 应用程序来将文件上传到 50 个服务器。而不是用户必须在下一个开始之前等待每次上传完成,我正在查看线程/后台工作人员。上传完成后,我想将上传“完成/失败”的状态报告回 UI。据我了解,我需要为此使用后台工作人员,以便我知道任务何时完成。我知道使用线程我可以使用生产者/消费者队列或信号量一次运行给定数量的线程,但我不太确定如何通过后台工作人员实现这一点。

所以我的问题是,控制上传一次运行的后台工作人员的合理数量是多少,将其余工作排队的最佳方式是什么?

上传文件的大小没有限制,因此可能非常小或最多几 MB。

提前致谢。

编辑 - 我为每台同时运行的服务器测试了一个后台工作程序。结果比单个后台工作人员更快,但我不能说我对一次运行 50 多个后台工作人员完全满意,而且由于将来服务器数量可能会增加,我决定只坚持一个,这似乎足够快。我将来可能会考虑将工人人数增加到 2 或 3 名,但目前 1 名似乎就足够了。感谢大家的帮助。

谢谢

【问题讨论】:

    标签: c# .net c#-3.0


    【解决方案1】:

    我会朝着完全不同的方向发展,tbh。您的应用程序应该获取文件并存储一次,响应客户端它得到它。然后应将该文件传播到其他服务器。您可以通过多种方式执行此操作,但如果您希望它由同一个应用程序控制(即不使用 Windows 服务等),那么一个好方法是使用消息队列(MSMQ 或 OS 之一) .

    【讨论】:

      【解决方案2】:

      这比使用信号量或生产者-消费者队列要容易得多。

      将所有任务放入队列中(不需要是线程安全队列,它只会在 UI 线程中使用)。

      从 1 到 N 循环,取出一个任务并启动一个BackgroundWorker。 (当开始的任务少于 N 时,请务必处理空队列)。在 RunWorkerCompleted 事件中,更新您的 UI,使另一个任务出列,然后启动另一个 BackgroundWorker

      【讨论】:

      • 嗨,Ben,我决定将这种方法用于我的应用程序,一次运行一个后台工作程序。感谢 fedor333 的帮助
      【解决方案3】:

      这里的瓶颈将是您的网络带宽。如果您的本地上游连接速度如此之快,以至于您可以使两个或更多远程主机上的传入连接饱和,那么您将从并行运行多个上传中受益。如果不是,那么它对总上传时间的影响很小,因为它将由(文件大小 * 上传数量)/(本地带宽)决定。换句话说 - 如果您一次上传 20 个,则需要一个小时;如果您同时进行 20 次上传,则仍需要一个小时。第一种方法的优点是,如果您失去连接,您只需要恢复/重新启动一次上传 - 无论连接断开时正在进行的上传。

      因此,我会使用单个后台线程依次将文件依次上传到每个服务器。如果您使用 .NET BackgroundWorker 来执行此操作,则可以在每个文件的末尾将其发送到 ReportProgress(并且您提前知道要上传多少文件,以便以百分比计算进度),并附上进度更新的一些自定义状态,以通知用户上次上传是否成功。

      【讨论】:

      • 嗨 Dylan - 我决定按照你的建议使用一名后台工作人员 - 谢谢 fedor333
      【解决方案4】:

      唯一确定的方法是测试和测量,但它可能因机器而异,主要取决于上行链路速度。

      同时启动 50 个后台工作人员有点高端,但数量并不多。一个简单的方法是同时启动 50 个并测量内存消耗和上传速度。

      如果每个 FTP 服务器都比客户端的上行速度快得多,那么最有效的方法是一次只上传一个(或可能两个)。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-06-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-06-05
        • 1970-01-01
        相关资源
        最近更新 更多