使用webclient DownloadFileAsync多个文件

时间:2011-02-19 01:00:31

标签: c# asynchronous webclient

描述
使用webclient的DownloadFileAsync下载多个文件,并使用文本文件进行URL输入以供下载。

问题
我使用的方法根本不会下载文件。只是跑步而且什么都不做。它填充列表数组然后退出程序而不下载单个文件。我已经google了解决方案,但缺乏信心。然后尝试在此处搜索数据库中的解决方案,结果相同。任何帮助表示赞赏。

问题

  1. 为什么这种做法不起作用?
  2. 我可以做些什么来改善这一点并从中吸取教训。
  3. 代码
    DownloadClass.cs

    using System;
    using System.ComponentModel;
    using System.Collections.Generic;
    using System.Net;
    using System.Threading;
    using System.Windows.Forms;
    
    namespace ThreadTest
    {
        class DownloadClass
        {
            public struct download
            {
                public static string URL { get; set; }
                public static string file { get; set; }
                public static string[] link;
                public static int downloadcount;
            }
    
            public static List<string> list = new List<string>();
            public static WebClient wc = new WebClient();
    
            public static void Download()
            {
                int count = 0;
                download.URL = list[0];
                Uri URI = new Uri(download.URL);
                UriBuilder uri = new UriBuilder(URI);
                download.link = uri.Path.ToLower().Split(new char[] { '/' });
    
                count = 0;
                // Find file
                foreach (string abs in download.link)
                {
                    count++;
                    if (abs.ToLower().Contains(".html") || abs.ToLower().Contains(".exe") || abs.ToLower().Contains(".txt"))
                    {
                        try
                        {
                            download.file = download.link[count];
                            wc.Proxy = null;
                            wc.DownloadFileCompleted += new AsyncCompletedEventHandler(wc_DownloadFileCompleted);
                            wc.DownloadFileAsync(URI, Application.StartupPath + "\\" + download.file);
                            break;
                        }
                        catch (Exception)
                        { }
                    }
                }
            }
    
            public static void BeginDownload()
            {
                new Thread(Download).Start();
            }
    
            public static void wc_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e)
            {
                int count = 0;
                download.downloadcount++;
                download.URL = list[0];
                Uri URI = new Uri(download.URL);
                UriBuilder uri = new UriBuilder(URI);
    
                download.link = uri.Path.ToLower().Split(new char[] { '/' });
    
                count = 0;
                // Find file
                foreach (string abs in download.link)
                {
                    count++;
                    if (abs.ToLower().Contains(".html") || abs.ToLower().Contains(".exe") || abs.ToLower().Contains(".txt"))
                    {
                        try
                        {
                            download.file = download.link[count];
                        }
                        catch (Exception)
                        { }
                    }
                }
                list.RemoveAt(0);
                if (list.Count > 0)
                {
                    wc.DownloadFileAsync(URI, list[download.downloadcount], Application.StartupPath + "\\" + download.file);
                }
                else
                {
                    Console.WriteLine("Downloading is done.");
                    Environment.Exit(0);
                }
            }
        }
    }
    

    Program.cs(主类)

    using System;
    using System.IO;
    using System.Collections.Generic;
    using System.Windows.Forms;
    
    namespace ThreadTest
    {
        class Program
        {
            static void Main(string[] args)
            {
                if (args.Length < 1)
                {
                    Console.WriteLine("Usage: {0} <download txtfile>", Environment.GetCommandLineArgs()[0]);
                    Environment.Exit(0);
                }
    
                int counter = 0;
                string line;
                string format = string.Format("{0}\\{1}", Application.StartupPath, args[0]);
    
                // Read the file line by line.
                using(StreamReader file = new StreamReader(format))
                {
                    while ((line = file.ReadLine())!= null)
                    {
                        // Store urls in a list.
                        DownloadClass.list.Add(line);
                        counter++;
                    }
                }
                DownloadClass.BeginDownload();
            }
        }
    }
    

1 个答案:

答案 0 :(得分:3)

除了糟糕的设计之外,还有很多问题导致你的代码没有(或者没有正确地工作)。

  1. 您需要确保应用程序在下载内容时存在。您当前的应用程序会立即退出(您必须等待主要内容的下载完成)。
  2. 你的应用程序可能会多次下载同一个文件,但根本不能下载其他文件(当访问静态对象时,你需要完全锁定对象,就像这里的async =多线程一样)BTW:不要使用静态对象首先要避免这种情况。
  3. 即使2被更正,它仍然可以将同一文件多次下载到同一文件名中,从而失败。
  4. 只要您不了解多线程,我建议您使用同步方法来避免所有这些问题。