Обработка загрузки нескольких десятков тысяч файлов C#
Я делаю небольшое программное обеспечение, которое загружает несколько десятков тысяч файлов. На данный момент это вообще не эффективно, потому что я скачиваю каждый файл один раз за раз, и поэтому он очень медленный, и много файлов меньше, чем 100ko.
Есть идеи улучшить скорость загрузки?
/*******************************
Worker work
/********************************/
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
listCount = _downloadList.Count;
// no GUI method !
while (TotalDownloadFile < _downloadList.Count)
{
// handle closing form during download
if (_worker.CancellationPending)
{
_mainView = null;
_wc.CancelAsync();
e.Cancel = true;
}
else if (!DownloadInProgress && TotalDownloadFile < listCount)
{
_lv = new launcherVersion(_downloadList[TotalDownloadFile]);
var fileToDownloadPath = Info.getDownloadUrl() + _lv.Path;
var saveFileToPath = Path.GetFullPath("./") + _lv.Path;
if (Tools.IsFileExist(saveFileToPath))
File.Delete(saveFileToPath); // remove file if extist
else
// create directory where the file will be created (use api this don't do anything on existing directory)
Directory.CreateDirectory(Path.GetDirectoryName(saveFileToPath));
StartDownload(fileToDownloadPath, saveFileToPath);
UpdateRemaingFile();
_currentFile = TotalDownloadFile;
}
}
}
Начать загрузку
/*******************************
start the download of files
/********************************/
public void StartDownload(string fileToDownloadLink, string pathToSaveFile)
{
try
{
using (_wc = new WebClient())
{
_wc.DownloadProgressChanged += client_DownloadProgressChanged;
_wc.DownloadFileCompleted += client_DownloadFileCompleted;
_wc.DownloadFileAsync(new Uri(fileToDownloadLink), pathToSaveFile);
DownloadInProgress = true;
}
}
catch (WebException e)
{
MessageBox.Show(fileToDownloadLink);
MessageBox.Show(e.ToString());
_worker.CancelAsync();
Application.Exit();
}
}
1 ответ
Расширяя мой комментарий. Вы можете потенциально использовать многопоточность и параллелизм для одновременной загрузки целых пакетов. Однако вам придется приложить некоторые усилия, чтобы убедиться, что каждый поток завершается успешно, и чтобы файлы не загружались дважды. Вы должны были бы защитить свои централизованные списки, используя что-то вроде блокировки.
Я бы лично реализовал 3 отдельных списка: ReadyToDownload
, DownloadInProgress
, а также DownloadComplete
,
ReadyToDownload
будет содержать все объекты, которые должны быть загружены. DownloadInProgress
будет содержать как загружаемый элемент, так и задачу, обрабатывающую загрузку. DownloadComplete
будет содержать все объекты, которые были загружены и ссылаются на задачу, которая выполнила загрузку.
Каждая задача будет гипотетически работать лучше как экземпляр пользовательского объекта. Этот объект будет ссылаться на каждый из списков, и он будет обрабатывать обновление списков, когда он будет работать, либо завершится, либо завершится неудачно. В случае сбоя вы можете либо добавить четвертый список для размещения неисправных элементов, либо повторно вставить их в ReadyToDownload
список.