DownloadFileAsync несколько файлов с помощью веб-клиента - PullRequest
3 голосов
/ 19 февраля 2011

Описание
Загрузите несколько файлов, используя функцию DownloadFileAsync веб-клиента и используя текстовый файл для ввода URL-адреса для загрузки.

Задача
Подход, который я использовал, не загружает файлы вообще. Просто бежит и ничего не делает. Он заполняет массив списка, затем выходит из программы, не загружая ни одного файла. Я гуглил решения, но придумал нехватку. Затем попытался найти решение в базе данных здесь с теми же результатами. Любая помощь приветствуется.

Вопросы

  1. Почему этот подход не работает?
  2. Что я могу сделать, чтобы улучшить это и извлечь из этого уроки.

Код
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 Ответ

3 голосов
/ 19 февраля 2011

Помимо плохого дизайна, есть много проблем, которые приводят к тому, что ваш код не работает (или работает неправильно).

  1. Вы должны убедиться, что ваше приложение работает, пока оно что-то загружает.Ваше текущее приложение сразу же закрывается (вам нужно дождаться завершения загрузки в главном окне).
  2. Ваше приложение может загружать один и тот же файл несколько раз, но не загружать другие вообще (вам нужно полностью заблокировать объект, когдаони используются асинхронно = многопоточным способом, как здесь, при доступе к статическим объектам. Кстати: вообще не используйте статические объекты, чтобы вообще избежать этого.
  3. Даже если исправлено 2, оно все равно может загрузитьодин и тот же файл несколько раз в одном и том же имени файла и, следовательно, не может.

Поскольку у вас нет знаний о многопоточности, я бы рекомендовал использовать синхронные методы, чтобы избежать всех этих проблем.

...