简体   繁体   English

有关穿线/背景工人的问题

[英]Question regarding threading/background workers

I have a question around threading and background workers that I hope you can help with. 我有一个关于线程和后台工作人员的问题,希望您能提供帮助。

I plan on making an ftp application to upload a file to 50 servers. 我计划制作一个ftp应用程序,以将文件上传到50台服务器。 Rather than the user having to wait for each upload to finish before the next one starts I was looking at threading/background workers. 而不是用户必须等待下一次上传完成之前的所有工作,我查看的是线程/后台工作人员。 Once an upload finishes I want to report the status of the upload "completed/failed" back to the UI. 上传完成后,我想向UI报告上传“完成/失败”的状态。 From my understanding, I will need to use background workers for this so I know when the task has completed. 据我了解,我将需要使用后台工作人员,这样我才能知道任务何时完成。 I know with threading I can use producer/consumer queue or a semaphore to run a given amount of threads at once but I am not quite sure how I can achieve this with back ground workers. 我知道通过线程我可以使用生产者/消费者队列或信号量来一次运行给定数量的线程,但是我不确定如何使用后台工作人员来实现这一点。

So my question is, what would be a sensible number of background workers controlling uploading to run at once and what would be the best way to queue the rest? 所以我的问题是,有多少明智的后台工作者控制上传一次运行,什么是最好的排队方式?

There is no limit on the size of the upload file so this could be quite small or up to a few MB. 上载文件的大小没有限制,因此它可能很小或最多几个MB。

Thanks in advance. 提前致谢。

Edit - I tested out one backgroundworker for each server running simultaneousness. 编辑-我为每个同时运行的服务器测试了一个后台工作人员。 The results where faster than just a single backgroundworker but I can't say that i was fully comfortable with running 50 plus background workers at once and since the server count may increase in the future, I decided to stick with just the one, which seems to be fast enough. 结果比仅一个后台工作人员快,但是我不能说我完全可以同时运行50个以上的后台工作人员,并且由于将来服务器数量可能会增加,我决定只使用一个,足够快。 I may in future look at increasing the count of workers to 2 or 3 but currently 1 seems to be adequate. 我将来可能会考虑将工人人数增加到2或3,但目前看来1个就足够了。 Thanks for everyones help. 谢谢大家的帮助。

Thanks 谢谢

I'd go in a completely different direction with it, tbh. 我会朝着完全不同的方向前进,TBH。 Your app should take the file and store it once, responding to the client that it's got it. 您的应用应获取该文件并将其存储一次,并向客户端做出响应。 The file should then be propagated to the other servers. 然后,该文件应传播到其他服务器。 You can do this many ways, but if you want it controlled by the same application (ie not done using a windows service or the like) then a good way would be to use a message queue (either MSMQ or one of the OS ones). 您可以通过多种方式执行此操作,但是如果您希望它由同一应用程序控制(即不使用Windows服务等操作),那么一种好方法是使用消息队列(MSMQ或操作系统之一) 。

The bottleneck here is going to be your network bandwidth. 这里的瓶颈将是您的网络带宽。 If your local upstream connection is so fast that you can saturate the incoming connections on two or more remote hosts, then you'll benefit from running multiple uploads in parallel. 如果本地上游连接速度如此之快,以至于您可以使两个或更多远程主机上的传入连接饱和,那么您将受益于并行运行多个上传。 If not, then it makes very little difference to the total upload time, since it'll be dictated by (file size * number of uploads) / (local bandwidth). 如果不是,那么它对总上传时间的影响很小,因为它取决于(文件大小*上传数量)/(本地带宽)。 In other words - if you do 20 uploads one at a time, it'll take an hour; 换句话说-如果您一次上传20次,则需要一个小时; if you do 20 uploads in parallel, it'll still take an hour. 如果您并行进行20次上传,则仍然需要一个小时。 The advantage of the first approach is that if you lose connectivity you'll only need to resume/restart a single upload - whichever one was in progress when the connection was lost. 第一种方法的优点是,如果您失去连接,则只需恢复/重新启动单个上传-连接中断时正在进行的任何上传。

I'd therefore use a single background thread to sequentially upload the file to each server in turn. 因此,我将使用单个后台线程依次将文件依次上传到每个服务器。 If you're using the .NET BackgroundWorker to do this, you can get it to ReportProgress at the end of each file (and you know in advance how many files are to be uploaded so you can calculate progress as a percentage), and attach some custom state to the progress update to inform the user whether the last upload succeeded or not. 如果您使用.NET BackgroundWorker进行此操作,则可以将其添加到每个文件末尾的ReportProgress(并且您预先知道要上传多少个文件,以便可以按百分比计算进度)并附加进度更新的某些自定义状态,以通知用户上次上传是否成功。

The only way to know for sure is to test and measure, but it can be different from machine to machine, mostly depending on uplink speed. 唯一可以确定的方法就是进行测试和测量,但是它在机器之间可能会有所不同,这主要取决于上行链路速度。

Starting 50 backgroundworkers at the same time is a bit on the high end, but is not incredibly many. 同时启动50个背景工作人员有点高端,但并不是很多。 A simple approach would be to start 50 all at the same time and measure memory consumption and upload speed. 一种简单的方法是同时启动全部50个并测量内存消耗和上载速度。

If the FTP servers are each much faster than the client uplink speed the most efficient would be to just upload one (or possibly two) at a time. 如果每个FTP服务器都比客户端上行链路速度快得多,那么最有效的方法就是一次仅上传一个(或两个)。

This is much easier than using a semaphore or producer-consumer queue. 这比使用信号量或生产者-消费者队列要容易得多。

Put all your tasks in a queue (doesn't need to be a thread-safe queue, it will only be used from the UI thread). 将所有任务放在一个队列中(不需要是线程安全的队列,它只会在UI线程中使用)。

Loop from 1 to N, taking out a task and starting a BackgroundWorker . 从1循环到N,执行任务并启动BackgroundWorker (Be sure to handle the empty queue, when there were less than N tasks to begin with). (当开始的任务少于N个时,请确保处理空队列)。 In the RunWorkerCompleted event, update your UI, dequeue another task, and start another BackgroundWorker . RunWorkerCompleted事件中,更新您的UI,使另一个任务出队,然后启动另一个BackgroundWorker

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM