【问题标题】:How to make webclient download file again if failed?如果失败,如何再次制作 webclient 下载文件?
【发布时间】:2023-03-14 09:19:01
【问题描述】:

我正在尝试使用 foreach 将图像链接列表下载到我的服务器(最多 40 个链接)。

在我的情况下,有时链接存在,但我不知道为什么它会捕获并取消下一个链接的下载。也许它需要等待一点?因为当我调试应用程序时,我看到链接是应用程序跳过并去捕获的可用但有时它在我的浏览器中几秒钟后打开,所以我尝试下载的服务器的响应时间有时需要更多时间来加载和打开链接。

   string newPath = "~/data/" + model.PostID + "/" + name + "/";

   //test1 is a list of links
                foreach (var item1 in test1)
                {

                    HttpWebRequest request = WebRequest.Create(item1) as HttpWebRequest; request.Method = "HEAD";
                    try
                    {
                        using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
                        {
                            var webClient = new WebClient();
                            string path = newPath + i + ".jpg";
                            webClient.DownloadFileAsync(new Uri(item1), Server.MapPath(path));
                            string newlinks = "https://example.com/data/" + chapter.PostID + "/" + name + "/" + i + ".jpg";
                            allimages = allimages + newlinks + ',';
                            response.Close();
                            i++;

                        }
                    }

                    catch
                    {                           
                        break;
                    }



                }

现在我的主要目标是解决这个问题,但正如我在调试中看到的那样:

  1. 我尝试下载的图片链接存在

  2. 有时需要更多时间来响应

那么我该如何解决这个问题?当下载取消并且存在链接时,我该怎么办?

【问题讨论】:

标签: c# webclient


【解决方案1】:

你可以使用这个例子:

    class WebClientUtility : WebClient
    {
        public int Timeout { get; set; }

        public WebClientUtility() : this(60000) { }

        public WebClientUtility(int timeout)
        {
            this.Timeout = timeout;
        }

        protected override WebRequest GetWebRequest(Uri address)
        {
            var request = base.GetWebRequest(address);
            if (request != null)
            {
                request.Timeout = Timeout;
            }
            return request;
        }
    }

    //
    public class DownloadHelper : IDisposable
    {
        private WebClientUtility _webClient;
        private string _downloadUrl;
        private string _savePath;
        private int _retryCount;

        public DownloadHelper(string downloadUrl, string savePath)
        {
            _savePath = savePath;
            _downloadUrl = downloadUrl;

            _webClient = new WebClientUtility();

            _webClient.DownloadFileCompleted += ClientOnDownloadFileCompleted;
        }


        public void StartDownload()
        {
            _webClient.DownloadFileAsync(new Uri(_downloadUrl), _savePath);
        }

        private void ClientOnDownloadFileCompleted(object sender, AsyncCompletedEventArgs e)
        {
            if (e.Error != null)
            {
                _retryCount++;

                if (_retryCount < 3)
                {
                    _webClient.DownloadFileAsync(new Uri(_downloadUrl), _savePath);
                }
                else
                {
                    Console.WriteLine(e.Error.Message);
                }
            }
            else
            {
                _retryCount = 0;
                Console.WriteLine($"successfully download: # {_downloadUrl}  to  # {_savePath}");
            }
        }
        public void Dispose()
        {
            _webClient.Dispose();
        }
    }

    //
    class Program
    {

        private static void Main(string[] args)
        {
            for (int i = 0; i < 100; i++)
            {
                var downloadUrl = $@"https://example.com/mag-{i}.pdf";
                var savePath = $@"D:\DownloadFile\FileName{i}.pdf";

                DownloadHelper downloadHelper = new DownloadHelper(downloadUrl, savePath);

                downloadHelper.StartDownload();
            }

            Console.ReadLine();
        }
    }

要解决超时问题,您可以创建派生类并设置基 WebRequest 类的超时属性,然后 对于重试,您可以使用 WebClient 的 DownloadFileCompleted 事件并在那里实现您的重试模式

【讨论】:

    【解决方案2】:

    您正在使用'DownloadFileAsync' 的异步版本。但是,您不是 awaiting 来电,这会导致无法预料的行为一团糟。

    创建你的方法async,然后使用这个:

    await webClient.DownloadFileAsync(new Uri(item1), Server.MapPath(path));
    

    【讨论】:

      【解决方案3】:

      这解决了我的问题:

      await Task.Run(() =>
                      {
                          webClient.DownloadFileAsync(new Uri(item1), Server.MapPath(path));
                      });
      

      【讨论】:

        猜你喜欢
        • 2019-09-13
        • 1970-01-01
        • 1970-01-01
        • 2015-10-06
        • 1970-01-01
        • 2021-02-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多