在并行文件下载器中引发进度事件同时最小化锁定的最佳方法

本文关键字:最小化 锁定 方法 最佳 事件 文件下载 并行 | 更新日期: 2023-09-27 18:06:21

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

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

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

在并行文件下载器中引发进度事件同时最小化锁定的最佳方法

您可以使用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();

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