0

我正在开发一个小文件下载器。它通过分段下载文件,然后并行下载每个分段。我希望我的应用程序支持一个事件系统,理想情况下它会显示已经完成的总进度。

我目前的幼稚方法是简单地锁定数据结构,每次每个线程下载 10k 时,所有线程都在其中存储有关其当前进度的信息。然后我进行计算,然后引发事件。这有一个问题,即线程通常会同时引发一个事件,而且每次我想引发一个事件时,我都会锁定整个结构。另一方面,如果连接变慢,则可能需要一段时间才能引发事件。我更希望有一个每 100 毫秒或某事会引发一个事件的系统。

虽然该解决方案有效,但我对此并不满意。对于所描述的情况,正确的方法是什么?

4

1 回答 1

3

您可以使用BlockingCollection作为所有线程写入其进度信息的队列。然后有另一个线程存在只是为了从 BlockingCollection 中取出项目

你的出队头可能看起来像

foreach (var progressMessage in progressMessageQueue.GetConsumingEnumerable())
{
    // Handle progressMessage by raising an event.
}

假设你有一个ProgressMessage封装了进度信息的类,你可以像这样声明队列:

BlockingCollection<ProgressMessage> progressMessageQueue = new BlockingCollection<ProgressMessage>();

您将项目添加到队列中,这样:

progressMessageQueue.Add(progressMessage);

当您知道所有线程都已完成工作时,请调用:

progressMessageQueue.CompleteAdding();

就每隔几毫秒排队进度消息而言;这要困难得多。如果文件块的下载速度不够快,则必须进行某种超时处理。我不知道你会怎么做,因为我不知道你是如何下载文件的。

于 2013-03-29T08:46:00.940 回答