2016-06-18 1 views
0

Я пытаюсь создать небольшое приложение, где, когда я ввожу список из 100 000 до 200 0000 URL-адресов, он должен пойти и загрузить html и сохранить его в относительной папке ,Использование Webclient с Foreach Loop для загрузки веб-страниц Около 100 000

У меня есть 2 решения, но у каждого есть некоторые проблемы, которые я пытаюсь найти наилучшим образом.

Первое решение: Синхронизировать метод

Ниже приведен код, я использую

currentline = 0; 
       var lines = txtUrls.Lines.Where(line => !String.IsNullOrWhiteSpace(line)).Count(); 
       string urltext = txtUrls.Text; 
       List<string> list = new List<string>(
          txtUrls.Text.Split(new string[] { "\r\n" }, 
          StringSplitOptions.RemoveEmptyEntries)); 

       lblStatus.Text = "Working"; 
       btnStart.Enabled = false; 

       foreach (string url in list) 
       { 
        using (WebClient client = new WebClient()) 
        { 
         client.DownloadFile(url, @".\pages\page" + currentline + ".html"); 
         currentline++; 
        } 
       } 

       lblStatus.Text = "Finished"; 
       btnStart.Enabled = true; 

код работает отлично, однако это медленно, а также случайным образом после 5000 адресов он перестает работать, и процесс говорит она завершена. (Обратите внимание, я использую этот код на фон рабочего, но сделать этот код проще для просмотра я показываю только соответствующий код.)

Второго решения: асинхронизировать Метод

int currentline = 0; 

       string urltext = txtUrls.Text; 
       List<string> list = new List<string>(
          txtUrls.Text.Split(new string[] { "\r\n" }, 
          StringSplitOptions.RemoveEmptyEntries)); 

       foreach (var url in list) 
       { 
        using (WebClient webClient = new WebClient()) 
        { 
         webClient.DownloadFileCompleted += new AsyncCompletedEventHandler(Completed); 
         webClient.DownloadProgressChanged += new DownloadProgressChangedEventHandler(ProgressChanged); 
         webClient.DownloadFileAsync(new Uri(url), @".\pages\page" + currentline + ".html"); 
        } 

        currentline++; 
        label1.Text = "No.of Lines Completed: " + currentline; 
       } 

этот код работает очень быстро, но большинство я получаю загруженные файлы с 0 КБ, и я уверен, что сеть работает быстро, так как я тестирую сервер OVH Dedi.

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

+0

Для первого решения попробуйте извлечь страницу для отдельного потока или задачи. Когда вы загружаете загрузку в основной рабочий поток, тогда ui не обновляется, и приложение не отвечает. Второй метод, который вы пытаетесь использовать асинхронный подход. Есть два способа, как это сделать. Используйте метод и метод begin и end, заканчивающиеся на async. Начинающие и конечные методы представляют собой более старые async-представления, тогда как методы, заканчивающиеся на слово «async», используются для использования async-ключевых слов. Ваше решение сочетает эти два способа вместе. –

ответ

0

Вместо использования DownloadFile() пытаются использовать

public async Task GetData() 
{ 
     WebClient client = new WebClient(); 
     var data = await client.DownloadDataTaskAsync("http://xxxxxxxxxxxxxxxxxxxxx"); 
} 

вы получите данные отформатированный в байт []. Затем вы просто вызываете: File.WriteAllBytes(), чтобы сохранить их на диск.

Смежные вопросы