/// <summary> /// The main program method /// </summary> /// <param name="args"> /// The arguments /// </param> public static void Main(string[] args) { var collection = new DownloadCollection( string.Empty, new List <IEnumerable <string> > { new List <string> { "A", "B" }, new List <string> { "D", "E", "F" }, new List <string> { "G", "H", "I" } }, "{0}{1}{2}"); var collection2 = new DownloadCollection( string.Empty, new List <IEnumerable <string> > { new List <string> { "1", "2" }, new List <string> { "3", "4", "5" }, new List <string> { "6", "7", "8" } }, "{0}{1}{2}") { Pause = 0 }; var manager = new DownloadManager(new List <DownloadCollection> { collection, collection2 }) { Downloader = new FakeDownloader(), LoggingAction = a => Console.WriteLine(a) }; manager.StartDownloading(); Console.WriteLine("Done"); Console.ReadKey(); }
/// <summary> /// Process a <see cref="DownloadCollection"/> collection. /// </summary> /// <param name="collection"> /// The collection to process /// </param> /// <param name="semaphore">The semaphore to limit the concurrent tasks</param> private void ProcessCollection(DownloadCollection collection, SemaphoreSlim semaphore) { foreach (var downloadItem in collection) { string item = downloadItem; Task.Factory.StartNew( async() => { semaphore.Wait(); Debug.WriteLine("Debugging"); InvokeResponse("Downloading {0}", item); await Downloader.Download(collection, item); InvokeResponse("Releasing {0}", item); Interlocked.Decrement(ref this._counter); semaphore.Release(); }); if (collection.Pause > 0) { InvokeResponse("Waiting {0} seconds after {1}", collection.Pause, item); Thread.Sleep(collection.Pause * 1000); } } }
/// <summary> /// Starts the download /// </summary> /// <param name="collection"> /// The collection. /// </param> /// <param name="file"> /// The name of the file to download. /// </param> /// <returns> /// Whether to continue or move to the next enumeration /// </returns> public async Task <bool> Download(DownloadCollection collection, string file) { await Task.Factory.StartNew(() => Thread.Sleep(5000)); return(true); }
/// <summary> /// Starts the download /// </summary> /// <param name="collection"> /// The collection. /// </param> /// <param name="file"> /// The name of the file to download. /// </param> /// <returns> /// Whether to continue or move to the next enumeration /// </returns> public async Task <bool> Download(DownloadCollection collection, string file) { bool returnValue = false; string remoteFile = Path.Combine(collection.RemotePath, file); string localFile = Path.Combine(collection.LocalPath, file); var request = (HttpWebRequest)WebRequest.Create(remoteFile); request.Credentials = new NetworkCredential(collection.UserName, collection.Password); Stream reader = null; FileStream fileStream = null; try { int startPosition = FileLength(localFile); request.AddRange(startPosition); var response = await request.GetResponseAsync() as HttpWebResponse; if (response != null && (response.StatusCode == HttpStatusCode.OK || response.StatusCode == HttpStatusCode.PartialContent)) { Console.WriteLine("Downloading {0} ({1} bytes)", file, response.ContentLength); reader = response.GetResponseStream(); fileStream = new FileStream(localFile, FileMode.Append, FileAccess.Write, FileShare.None); if (reader != null) { // It will store the current number of bytes we retrieved from the server int bytesSize; // A buffer for storing and writing the data retrieved from the server var downBuffer = new byte[2048]; int offset = 0; Console.WriteLine(); int totalSize = (int)fileStream.Length + (int)response.ContentLength; // Loop through the buffer until the buffer is empty while ((bytesSize = reader.Read(downBuffer, offset, downBuffer.Length)) > 0) { fileStream.Write(downBuffer, 0, bytesSize); offset = 0; } Console.WriteLine(); Console.WriteLine("Success: {0}", remoteFile); returnValue = true; } } } catch (IOException ex) { Console.WriteLine("File error: {0}", remoteFile); Console.Write(ex.Message); returnValue = true; } catch (WebException ex) { Console.WriteLine("Skipping file: {0}", file); returnValue = ((HttpWebResponse)ex.Response).StatusCode == HttpStatusCode.RequestedRangeNotSatisfiable; } catch (Exception ex) { Console.WriteLine("Failed: {0}", remoteFile); Console.Write(ex.Message); returnValue = false; } finally { if (reader != null) { reader.Close(); } if (fileStream != null) { fileStream.Close(); } } return(returnValue); }