I'm writing a mechanism to retry any failed downloads that respond with certain http error codes, I've noticed the server I'm downloading from will unexpectedly throw these codes to me and when I manually visit the URL it appears to be fine.
It also seems that its fine when trying to download for a second or (rarely) third time. The KeyValuePair represents the key as being the download link, and the value being the location where the file is set to be saved on the device.
I simply check if the file exists in the save location to determine if it actually downloaded.
public static class DownloadUtilities
{
public static void DownloadLinks(Dictionary<string, string> files)
{
Parallel.ForEach(
files,
new ParallelOptions { MaxDegreeOfParallelism = 20 },
DownloadLink);
}
private static void DownloadLink(KeyValuePair<string, string> link, bool retrying = false)
{
try
{
using (var webClient = new WebClient())
{
webClient.Headers.Add("User-Agent", "Mozilla/4.0 (compatible; MSIE 8.0)");
webClient.DownloadFile(new Uri(link.Key), link.Value);
}
}
catch (WebException e)
{
if (retrying) { return; } // Silently exit, we're retrying.
if (e.Status != WebExceptionStatus.ProtocolError)
{
throw;
}
if (e.Message.Contains("(504) Gateway Timeout") || e.Message.Contains("(403) Forbidden"))
{
if (!RetryFailedDownload(link))
{
Program.FailedDownloads.Add(link.Key); // Lets settle for the fact it can't download, and add it to the failed list.
}
}
else
{
Logger.Error("Failed to download: " + link.Key);
Logger.Error(e.Message);
}
}
}
private static bool RetryFailedDownload(KeyValuePair<string, string> link)
{
for (var i = 0; i < 4; i++) // Retry mechanism for 4 trys?
{
DownloadLink(link, true);
if (File.Exists(link.Value)) // It finally managed to download?
{
return true;
}
}
return false;
}
}
Program.FailedDownloads.Add(link.Key);
without logging and vice-versa? It would be very useful if you can provide some more information on how you expect this function to work. \$\endgroup\$