2015-12-12 7 views
0

Я пытаюсь загрузить несколько файлов с несколькими потоками. Программа использует алгоритм BFS для доступа ко всем файлам с заданным URL: http://www.police.am/Hanraqve/ Проблема в том, что один и тот же файл можно загружать несколько раз по мере выпуска нескольких потоков. Я думаю о способе синхронизации процесса загрузки, чтобы каждый файл загружался один раз только с помощью мьютексов или семафоров. Любая идея или реальный код будут очень оценены. Вот мой исходный кодЗагрузка нескольких файлов синхронно C#

public static async Task Download() 
    { 
     nodes.Enqueue(root); 
     while (nodes.Count() != 0) 
     { 
      String currentNode = ""; 
      if (nodes.TryDequeue(out currentNode)) 
      { 
       if (!visitedNodes.Contains(currentNode)) 
       { 
        visitedNodes.Add(currentNode); 
        if (isFolder(currentNode)) 
        { 
         List<String> urls = GetUrlsFromHtml(currentNode); 
         foreach (String url in urls) 
         { 
          nodes.Enqueue(url); 
         } 
        } 
        else 
        { 
         string fileName = currentNode.Remove(0, currentNode.LastIndexOf('/') + 1); 

         using (WebClient webClient = new WebClient()) 
         { 
          await webClient.DownloadFileTaskAsync(new Uri(currentNode), destinationFolderPath + @"\" + fileName); 
          files.Enqueue(destinationFolderPath + @"\" + fileName); 
         } 
        } 
       } 

      } 
     } 


     //cts.Cancel(); 
    } 

    public static List<String> GetUrlsFromHtml(string url) 
    { 
     HtmlWeb hw = new HtmlWeb(); 
     HtmlDocument doc = hw.Load(url); 
     List<String> urls = new List<String>(); 
     foreach (HtmlNode htmlNode in doc.DocumentNode.SelectNodes("//a[@href]")) 
     { 
      string hrefValue = htmlNode.Attributes["href"].Value; 
      if (hrefValue[0] >= '1' && hrefValue[0] <= '9') 
      { 
       urls.Add(url + hrefValue); 
      } 
     } 
     return urls; 
    } 

    public static bool isFolder(string url) 
    { 
     return url.EndsWith("/"); 
    } 
} 

}

+1

Почему загружено несколько раз? Может ли тот же файл отображаться в нескольких URL-адресах? –

+0

Например, один поток может передать , если (! VisitedNodes.Contains (currentNode)) строка , а другая добавляет узел в список посещенных узлов. Оба они загружат тот же файл. –

+0

Затем используйте поточно-безопасные коллекции. Я бы, возможно, изменил алгоритм. Пройдите каждый узел в графе и найдите все возможные файлы. Затем, и только тогда, выполните параллельные загрузки. –

ответ