DownloadFileAsync multiple files using webclient

荒凉一梦 提交于 2019-12-19 09:57:09

问题


Description
Download multiple files using webclient's DownloadFileAsync and utilizing a text file for URL input for download.

Problem
The approach that I have used won't download files at all. Just runs and does nothing. It fills the list array then quits the program without downloading a single file. I have googled for solutions but come up shorthanded. Then attempted to search for a solution in the database here with same results. Any help is appreciated.

Questions

  1. Why does this approach not work?
  2. What can I do to improve this and learn from this.

Code
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 (Main Class)

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:


Besides being bad design there are lots of issues that lead to your code not (or nor correctly working).

  1. You need to make sure that you application lives while it downloads something. Your current app quits right away (you have to wait for the downloading to complete in your main).
  2. You application may download the same file multiple times but not download others at all (You need to completely lock object when they are used in an async=multithreading way like here when accessing static objects) BTW: Don't use static objects at all to avoid that in the first place.
  3. Even if 2 is corrected it may still download the same file multiple times into the same filename and thus fail.

As long as you have no knowledge about multithreading I'd recommend you use the synchoneous methods to avoid all those problems.



来源:https://stackoverflow.com/questions/5048154/downloadfileasync-multiple-files-using-webclient

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!