使用不同的参数多次调用BackgroundWorker.RunWorkerAsync()

时间:2013-12-26 12:07:51

标签: c# .net multithreading backgroundworker

我正在尝试将文件上传到服务器。

我想将文件分成'n'大小的'y'大小,然后使用线程一次将'x'块一起上传到服务器。 当其中一个'x'块完成后,另一个块应该开始上传,直到没有剩余的块可以上传。

我一直在关注BackgroundWorker,并有以下实现方法:

1)以下方法分配给Worker.DoWork

private void ChunkUploaderDoWork(object sender, DoWorkEventArgs e) {
    //get arguments list form e.arguments and prepare next upload
    //The arguments list contains information such as next chunk number and chunk size etc..
    //Calculate file stream offset based on chunk size and upload the next y bytes.
}

2)然后我可以打电话

BackgroundWorker worker = new BackgroundWorker();
worker.DoWork += (obj, e) => WorkerDoWork();
worker.ProgressChanged += new ProgressChangedEventHandler (Worker_ProgressChanged);
worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler (Worker_RunWorkerCompleted);
worker.RunWorkerAsync(argumentsList);

使用backgroundWorker,我可以让它报告进度,也可以通知完成以便开始上传下一个块,所以这些是我想要使用它的几个原因。问题是我不确定是否应该按以下方式调用worker.RunWorkerAsync()(如果我一次上传4个块):

worker.RunWorkerAsync(argumentsListForChunk1);
worker.RunWorkerAsync(argumentsListForChunk2);
worker.RunWorkerAsync(argumentsListForChunk3);
worker.RunWorkerAsync(argumentsListForChunk4);

然后当任何一个工人完成并给我一个工人完成回电时,我就可以这样做:

void Worker_RunWorkerCompleted(object sender, ProgressChangedEventArgs e)
{
    //Check if we have any outstanding chunks and upload next chunk if available.
    //for example if we had chunk 5 next in line, then I could call RunWorkerAsync as follows:
    worker.RunWorkerAsync(argumentsListForChunk5);
}

我对c#比较陌生,想知道这是否是完成任务的好方法。

简而言之,我的要求是

  1. 使用线程上传文件块
  2. 限制线程数
  3. 检查已完成的主题,以便我们可以开始上传下一个文件块
  4. 跟踪线程进度。
  5. 任何帮助将不胜感激:)

    编辑:: @o_weisman和@HansPassant的评论让我意识到这个问题缺少以下相关信息。 我正在尝试上传到我控制的服务器。服务器限制连接速度,因此打开多个连接以上传文件块将导致超速提升。

    谢谢!

1 个答案:

答案 0 :(得分:2)

您无法将BackgroundWorker用于多个并发操作。 它旨在为UI提供服务,以便在后台执行一些操作,并在操作期间或之后更新UI。

对于多个并发操作,您最好使用Tasks。
1。每个任务大致一个不同的线程。
2。您可以根据需要创建任意数量,但您也可以使用Task工厂上的设置来限制并发线程数。
3。您可以通过多种方式等待任务,无论是单独还是单独,或者您可以将它们链接在一起,以便一旦完成,下一个使用它的结果并继续。
4。保持跟踪总是很棘手。后台工作者确实提供了一种方便的方法,因为它是面向UI的。我建议让一个后台工作者保持活动状态以从某个中央状态对象获得持续更新。

这包含了一个很好的解释: http://msdn.microsoft.com/en-us/library/dd537609(v=vs.110).aspx

相关问题