动态事件处理下载文件异步完成,并下载异步进度已更改

时间:2014-06-18 00:46:01

标签: c# .net

我试图创建一个tumblr图像下载器, 我的问题是当我需要一次下载100张图像。 我在谷歌搜索我无法使用一个对象webclient一次下载100张图像 所以我会在每次下载时创建新的webclient。 downloadasyncCompleted的问题是eventhandler,下载progresschanged总是一样的。 我怎么解决这个问题?

也许我的问题是错的 但我需要的是: 1.一次下载多个文件 2.使用动态创建的进度条控制progresschanged事件(进度条总数与图片下载量相同)

3 个答案:

答案 0 :(得分:1)

听起来你是在循环中调用“DownloadFileAsync”函数100次,然后以凌乱的顺序慢慢收回你的结果。我建议维护一个URI列表来下载和存储你所做的索引。在您的事件处理程序下载完成后,开始下载下一个对象。一次下载一个。

它不会“同时下载所有文件”,但无论如何这在功能上是不可能的,你不应该通过一次一个地丢失重要的下载性能。

回顾一下:

  • 建立要下载的URI列表(地址)
  • 跟踪当前正在下载的URI列表中的索引
  • 在下载完成的事件中,增加该索引并开始下一个索引,如果还有更多的话。

这样,每当下载完成被触发时,您就知道刚下载的文件是要下载的文件列表中[index]的URI后面的文件。

这也意味着您不需要为每个请求销毁和创建新的WebClient。

答案 1 :(得分:1)

使用允许您传递用户令牌的DownloadFileAsync overload。该令牌将显示在UserStateDownloadProgressChangedEventArgs的{​​{1}}属性中。所以,如果你有:

AsyncCompletedEventArgs

请注意,您可以将第三个参数中您喜欢的任何数据传递给WebClient client = new WebClient(); client.DownloadProgressChanged += DownloadProgressChangedHandler; client.DownloadFileCompleted += DownloadCompletedHandler; client.DownloadFileAsync(new Uri(urlToDownload), filename, urlToDownload); // ... void DownloadProgressChangedHandler(object sender, DownloadProgressChangedEventArgs e) { string urlToDownload = (string)e.UserState; // get the URL we're downloading from // do whatever } void DownloadCompletedHandler(object sender, AsyncCompletedEventArgs e) { string urlToDownload = (string)e.UserState; // get the URL we're downloading from // whatever } 。如果要传递多个字段,则需要创建具有属性的类,或者为多个字段创建Tuple。在任何一种情况下,您仍然会将DownloadFileAsync字段转换为它实际的任何类型,然后访问它。

答案 2 :(得分:0)

我将使用自己的Web客户端制作30个线程,然后使用字符串的ConcurrentQueue。然后推送所有uri只有队列然后启动他们可以有一段时间的所有线程(trydequque())然后每个线程可以dl。 30个线程工作得很好,四核PC。您可以使用下载,不需要以这种方式使用异步。

ConcurrentQueue<string> queue = new ConcurrentQueue<string>();

        queue.Enqueue("http://link.jpg");

        for (var x = 0; x < 30; x++)
        {
            new Thread(new ThreadStart(() =>
                {
                    //create webclient here
                    string uri;
                    while(queue.TryDequeue(out uri))
                    {
                        //download here
                    }
                })).Start();
        }