Как сделать так, чтобы веб-клиент снова скачивал файл, если не получилось? - PullRequest
0 голосов
/ 10 ноября 2018

Я пытаюсь загрузить список ссылок на изображения на свой сервер (до 40 ссылок), используя foreach.

В моем случае иногда ссылка существует, но я не знаю, почему она поймает и отменит загрузку следующей ссылки. Может быть, нужно немного подождать? потому что, когда я отлаживаю приложение, я вижу, что ссылка была пропущена и уловлена, приложение было доступно, но иногда оно открывается через несколько секунд в моем браузере, поэтому время отклика с сервера, который я пытаюсь загрузить, иногда требует больше времени для загрузки и открытия ссылка.

   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. Иногда требуется больше времени для ответа

Так как я могу это исправить? что делать после отмены загрузки и ссылки?

Ответы [ 3 ]

0 голосов
/ 10 ноября 2018

Вы используете асинхронную версию 'DownloadFileAsync'. Однако вы не awaiting вызов, который оставляет беспорядок с непредсказуемым поведением.

Сделайте свой метод async и затем используйте это:

await webClient.DownloadFileAsync(new Uri(item1), Server.MapPath(path));
0 голосов
/ 10 ноября 2018

Это решило мой случай:

await Task.Run(() =>
                {
                    webClient.DownloadFileAsync(new Uri(item1), Server.MapPath(path));
                });
0 голосов
/ 10 ноября 2018

Вы можете использовать этот пример:

    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 и для повторной попытки вы можете использовать событие DownloadFileCompleted WebClient и реализовать свой шаблон повторения там

...