Я пытаюсь загрузить несколько файлов с несколькими потоками. Программа использует алгоритм 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("/");
}
}
}
Почему загружено несколько раз? Может ли тот же файл отображаться в нескольких URL-адресах? –
Например, один поток может передать , если (! VisitedNodes.Contains (currentNode)) строка , а другая добавляет узел в список посещенных узлов. Оба они загружат тот же файл. –
Затем используйте поточно-безопасные коллекции. Я бы, возможно, изменил алгоритм. Пройдите каждый узел в графе и найдите все возможные файлы. Затем, и только тогда, выполните параллельные загрузки. –