/// <summary> /// Start to download. /// </summary> public void Download() { // Only idle download client can be started. if (this.Status != DownloadStatus.Initialized) { throw new ApplicationException( "Only Initialized download client can be started."); } this.EnsurePropertyValid(); // Set the status. this.Status = DownloadStatus.Downloading; if (!this.HasChecked) { this.CheckUrlAndFile(); } HttpDownloadClient client = new HttpDownloadClient( this.Url.AbsoluteUri, 0, long.MaxValue, this.BufferSize, this.BufferCountPerNotification * this.BufferSize, this.BufferCountPerNotification); // Set the HasChecked flag, so the client will not check the URL again. client.TotalSize = this.TotalSize; client.DownloadPath = this.DownloadPath; client.HasChecked = true; client.Credentials = this.Credentials; client.Proxy = this.Proxy; // Register the events of HttpDownloadClients. client.DownloadProgressChanged += client_DownloadProgressChanged; client.StatusChanged += client_StatusChanged; client.DownloadCompleted += client_DownloadCompleted; this.downloadClients.Add(client); client.Download(); }
void DownloadInternal(object obj) { if (this.Status != DownloadStatus.Waiting) { return; } try { this.EnsurePropertyValid(); // Set the status. this.Status = DownloadStatus.Downloading; if (!this.HasChecked) { this.CheckUrlAndFile(); } // If the file does not support "Accept-Ranges" header, then create one // HttpDownloadClient to download the file in a single thread, else create // multiple HttpDownloadClients to download the file. if (!IsRangeSupported) { HttpDownloadClient client = new HttpDownloadClient( this.Url.AbsoluteUri, 0, long.MaxValue, this.BufferSize, this.BufferCountPerNotification * this.BufferSize, this.BufferCountPerNotification); // Set the HasChecked flag, so the client will not check the URL again. client.TotalSize = this.TotalSize; client.DownloadPath = this.DownloadPath; client.HasChecked = true; client.Credentials = this.Credentials; client.Proxy = this.Proxy; this.downloadClients.Add(client); } else { // Calculate the block size for each client to download. int maxSizePerThread = (int)Math.Ceiling((double)this.TotalSize / this.MaxThreadCount); if (maxSizePerThread < this.MaxCacheSize) { maxSizePerThread = this.MaxCacheSize; } long leftSizeToDownload = this.TotalSize; // The real threads count number is the min value of MaxThreadCount and // TotalSize / MaxCacheSize. int threadsCount = (int)Math.Ceiling((double)this.TotalSize / maxSizePerThread); for (int i = 0; i < threadsCount; i++) { long endPoint = maxSizePerThread * (i + 1) - 1; long sizeToDownload = maxSizePerThread; if (endPoint > this.TotalSize) { endPoint = this.TotalSize - 1; sizeToDownload = endPoint - maxSizePerThread * i; } // Download a block of the whole file. HttpDownloadClient client = new HttpDownloadClient( this.Url.AbsoluteUri, maxSizePerThread * i, endPoint); // Set the HasChecked flag, so the client will not check the URL again. client.DownloadPath = this.DownloadPath; client.HasChecked = true; client.TotalSize = sizeToDownload; client.Credentials = this.Credentials; client.Proxy = this.Proxy; this.downloadClients.Add(client); } } // Set the lastStartTime to calculate the used time. lastStartTime = DateTime.Now; // Start all HttpDownloadClients. foreach (var client in this.downloadClients) { if (this.Proxy != null) { client.Proxy = this.Proxy; } // Register the events of HttpDownloadClients. client.DownloadProgressChanged += client_DownloadProgressChanged; client.StatusChanged += client_StatusChanged; client.DownloadCompleted += client_DownloadCompleted; client.BeginDownload(); } } catch (Exception ex) { this.Cancel(); this.OnDownloadCompleted(new DownloadCompletedEventArgs( null, this.DownloadedSize, this.TotalSize, this.TotalUsedTime, ex)); } }