c# - 使用 webclient DownloadFileAsync 多个文件

标签 c# asynchronous webclient

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

问题
我使用的方法根本不会下载文件。只是运行,什么也不做。它填充列表数组然后退出程序而不下载单个文件。我在谷歌上搜索了解决方案,但人手不足。然后尝试在此处的数据库中搜索具有相同结果的解决方案。感谢您的帮助。

问题

  1. 为什么这种方法不起作用?
  2. 我可以做些什么来改进它并从中学习。

代码
下载Class.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. 您需要确保您的应用程序在下载内容时仍然存在。您当前的应用程序会立即退出(您必须等待主程序中的下载完成)。
  2. 您的应用程序可能会多次下载同一个文件,但根本不会下载其他文件(当以异步=多线程方式使用对象时,您需要完全锁定对象,就像这里访问静态对象时一样)顺便说一句:不要使用静态对象一开始就避免这种情况。
  3. 即使 2 得到纠正,它仍可能会多次下载同一个文件到同一个文件名并因此失败。

只要您不了解多线程,我就建议您使用同步方法来避免所有这些问题。

关于c# - 使用 webclient DownloadFileAsync 多个文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5048154/

相关文章:

c# - 在 .NET MVC Controller 上,映射是什么?

c# - 如何在 C# 中获取网格的行数和列数?

c++ - 异常处理、WinRT C++ 并发异步任务

c# - 无法在 datagridview 单元格中显示完整图像

c# - 使用枚举是列出不同 "Types of Car"的最佳方式吗

c# - 使用 C#.Net 内置桌面软件在网站上编辑一段数据的可能性

c# - 服务器违反了协议(protocol)。 C# 中的 Section=ResponseStatusLine

Java + HtmlUnit WebClient + SSL 页面

java - Android异步USB读取到ByteBuffer,但无法确定大小

c# - Socket.SendAsync 需要几秒钟才能完成