/// <summary> /// 暂停下载. /// </summary> public void Pause() { // 只有正在下载的情况下才能暂停。 if (this.Status != HttpDownloadClientStatus.Downloading) { throw new ApplicationException("只有正在下载的客户端才能暂停。"); } // 主线程会检查状态。如果暂停了,下载将会被暂停,并且状态会变成暂停状态。 this.Status = HttpDownloadClientStatus.Pausing; }
/// <summary> /// Pause the download. /// </summary> public void Pause() { // Only downloading client can be paused. if (this.Status != HttpDownloadClientStatus.Downloading) { throw new ApplicationException("Only downloading client can be paused."); } // The backgound thread will check the status. If it is Pausing, the download // will be paused and the status will be changed to Paused. this.Status = HttpDownloadClientStatus.Pausing; }
/// <summary> /// 暂停下载 /// </summary> public void Pause() { // 只有正在下载的客户端才能暂停. if (this.Status != HttpDownloadClientStatus.Downloading) { throw new ApplicationException("只有正在下载的客户端才能暂停."); } // 后台线程会查看状态,如果状态时暂停的, // 下载将会被暂停并且状态将随之改为暂停. this.Status = HttpDownloadClientStatus.Pausing; }
/// <summary> /// 取消下载。 /// </summary> public void Cancel() { // 只有正在下载或者暂停的情况下才能被取消。 if (this.Status != HttpDownloadClientStatus.Paused && this.Status != HttpDownloadClientStatus.Downloading) { throw new ApplicationException("只有正在下载或者暂停的情况下才能被取消"); } // 主线程会检查状态,如果是取消,下载将会取消,状态同时改变成取消状态。 this.Status = HttpDownloadClientStatus.Canceling; }
/// <summary> /// 取消下载 /// </summary> public void Cancel() { // 只有正在下载的或者是暂停的客户端才能被取消. if (this.Status != HttpDownloadClientStatus.Paused && this.Status != HttpDownloadClientStatus.Downloading) { throw new ApplicationException("只有正在下载的或者是暂停的客户端" + "才能被取消."); } // 后台线程将查看状态.如果是正在取消, // 那么下载将被取消并且状态将改成已取消. this.Status = HttpDownloadClientStatus.Canceling; }
/// <summary> /// Cancel the download /// </summary> public void Cancel() { // Only a downloading or paused client can be canceled. if (this.Status != HttpDownloadClientStatus.Paused && this.Status != HttpDownloadClientStatus.Downloading) { throw new ApplicationException("Only a downloading or paused client" + " can be canceled."); } // The backgound thread will check the status. If it is Canceling, the download // will be canceled and the status will be changed to Canceled. this.Status = HttpDownloadClientStatus.Canceling; }
public HttpDownloadClient(int index, string url, string downloadPath, int startPoint, int endPoint, int bufferSize, int cacheSize, int bufferCountPerNotification) { if (startPoint < 0) { throw new ArgumentOutOfRangeException( "StartPoint cannot be less then 0. "); } if (endPoint < startPoint) { throw new ArgumentOutOfRangeException( "EndPoint cannot be less then StartPoint "); } if (bufferSize < 0) { throw new ArgumentOutOfRangeException( "BufferSize cannot be less then 0. "); } if (cacheSize < bufferSize) { throw new ArgumentOutOfRangeException( "MaxCacheSize cannot be less then BufferSize "); } if (bufferCountPerNotification <= 0) { throw new ArgumentOutOfRangeException( "BufferCountPerNotification cannot be less then 0. "); } this.StartPoint = startPoint; this.EndPoint = endPoint; this.BufferSize = bufferSize; this.MaxCacheSize = cacheSize; this.BufferCountPerNotification = bufferCountPerNotification; this.Url = new Uri(url, UriKind.Absolute); this.DownloadPath = downloadPath; // Set the idle status. this.status = HttpDownloadClientStatus.Idle; Index = index; }
public HttpDownloadClient(string url, string downloadPath, int startPoint, int endPoint, int bufferSize, int cacheSize, int bufferCountPerNotification) { if (startPoint < 0) { throw new ArgumentOutOfRangeException( "StartPoint不能小于0."); } if (endPoint < startPoint) { throw new ArgumentOutOfRangeException( "EndPoint不能小于StartPoint. "); } if (bufferSize < 0) { throw new ArgumentOutOfRangeException( "BufferSize不能小于0."); } if (cacheSize < bufferSize) { throw new ArgumentOutOfRangeException( "MaxCacheSize不能小于BufferSize."); } if (bufferCountPerNotification <= 0) { throw new ArgumentOutOfRangeException( "BufferCountPerNotification不能小于0. "); } this.StartPoint = startPoint; this.EndPoint = endPoint; this.BufferSize = bufferSize; this.MaxCacheSize = cacheSize; this.BufferCountPerNotification = bufferCountPerNotification; this.Url = new Uri(url, UriKind.Absolute); this.DownloadPath = downloadPath; // 设定空闲的状态 this.status = HttpDownloadClientStatus.Idle; }
public HttpDownloadClient(Uri url, string downloadPath, long startPoint, long endPoint, int bufferSize, int cacheSize) { if (startPoint < 0) { throw new ArgumentOutOfRangeException( "StartPoint cannot be less than 0. "); } if (endPoint < startPoint) { throw new ArgumentOutOfRangeException( "EndPoint cannot be less than StartPoint "); } if (bufferSize < 0) { throw new ArgumentOutOfRangeException( "BufferSize cannot be less than 0. "); } if (cacheSize < bufferSize) { throw new ArgumentOutOfRangeException( "MaxCacheSize cannot be less than BufferSize "); } this.StartPoint = startPoint; this.EndPoint = endPoint; this.BufferSize = bufferSize; this.MaxCacheSize = cacheSize; this.Url = url; this.DownloadPath = downloadPath; // Set the idle status. this.status = HttpDownloadClientStatus.Idle; }
/// <summary> /// Cancel the download /// </summary> public void Cancel() { // Only a downloading or paused client can be canceled. if (this.Status != HttpDownloadClientStatus.Paused && this.Status != HttpDownloadClientStatus.Downloading) { throw new ApplicationException("Only a downloading or paused client" + " can be canceled."); } // The backgound thread will check the status. If it is Canceling, the download // will be canceled and the status will be changed to Canceled. this.Status = HttpDownloadClientStatus.Canceling; }
/// <summary> /// 用 HttpWebRequest下载数据. 它从响应流中读取缓冲区的数据。 /// 并且先把数据存储在内存缓存中。 /// 如果缓存满了,或者下载被暂停,取消或者完成,就将缓存中的数据写成本地文件。 /// </summary> void Download() { HttpWebRequest webRequest = null; HttpWebResponse webResponse = null; Stream responseStream = null; MemoryStream downloadCache = null; // 设置状态。 this.Status = HttpDownloadClientStatus.Downloading; try { // 创建一个下载的请求。 webRequest = (HttpWebRequest)WebRequest.Create(Url); webRequest.Method = "GET"; webRequest.Credentials = CredentialCache.DefaultCredentials; // 指定下载的模块。 if (EndPoint != long.MaxValue) { webRequest.AddRange(StartPoint + DownloadedSize, EndPoint); } else { webRequest.AddRange(StartPoint + DownloadedSize); } // 设置 proxy. if (Proxy != null) { webRequest.Proxy = Proxy; } // 得到从服务器中的响应和响应流。 webResponse = (HttpWebResponse)webRequest.GetResponse(); responseStream = webResponse.GetResponseStream(); // 在内存中缓存数据。 downloadCache = new MemoryStream(this.MaxCacheSize); byte[] downloadBuffer = new byte[this.BufferSize]; int bytesSize = 0; int cachedSize = 0; // 下载文件,知道被取消,暂停或者完成。 while (true) { // 从响应流中读取缓冲数据。 bytesSize = responseStream.Read(downloadBuffer, 0, downloadBuffer.Length); // 如果缓存满了,或者下载被暂停,取消,或者完成了,将缓存数据写成本地文件。 if (this.Status != HttpDownloadClientStatus.Downloading || bytesSize == 0 || this.MaxCacheSize < cachedSize + bytesSize) { try { // 将缓存数据写成本地文件。 WriteCacheToFile(downloadCache, cachedSize); this.DownloadedSize += cachedSize; // 停止下载文件,如果下载被暂停,取消,或者完成。 if (this.Status != HttpDownloadClientStatus.Downloading || bytesSize == 0) { break; } // 重新设置缓存。 downloadCache.Seek(0, SeekOrigin.Begin); cachedSize = 0; } catch (Exception ex) { //触发 DownloadCompleted事件。 this.OnError(new ErrorEventArgs { Error = ex }); return; } } // 从缓冲区写入数据到内存中的缓存。 downloadCache.Write(downloadBuffer, 0, bytesSize); cachedSize += bytesSize; // 触发DownloadProgressChanged事件。 OnDownloadProgressChanged( new HttpDownloadClientProgressChangedEventArgs { Size = bytesSize }); } // 更新状态。当状态是暂停,取消,完成时,上面的循环将会停止。 if (this.Status == HttpDownloadClientStatus.Pausing) { this.Status = HttpDownloadClientStatus.Paused; } else if (this.Status == HttpDownloadClientStatus.Canceling) { this.Status = HttpDownloadClientStatus.Canceled; Exception ex = new Exception("下载被用户取消 "); this.OnError(new ErrorEventArgs { Error = ex }); } else { this.Status = HttpDownloadClientStatus.Completed; return; } } finally { // 当以上代码执行结束时,关闭流。 if (responseStream != null) { responseStream.Close(); } if (webResponse != null) { webResponse.Close(); } if (downloadCache != null) { downloadCache.Close(); } } }
/// <summary> /// Download the data using HttpWebRequest. It will read a buffer of bytes from the /// response stream, and store the buffer to a MemoryStream cache first. /// If the cache is full, or the download is paused, canceled or completed, write /// the data in cache to local file. /// </summary> void Download() { HttpWebRequest webRequest = null; HttpWebResponse webResponse = null; Stream responseStream = null; MemoryStream downloadCache = null; lastStartTime = DateTime.Now; // Set the status. this.Status = HttpDownloadClientStatus.Downloading; try { // Create a request to the file to be downloaded. webRequest = (HttpWebRequest)WebRequest.Create(Url); webRequest.Method = "GET"; webRequest.Credentials = CredentialCache.DefaultCredentials; // Specify the block to download. if (EndPoint != int.MaxValue) { webRequest.AddRange(StartPoint + DownloadedSize, EndPoint); } else { webRequest.AddRange(StartPoint + DownloadedSize); } // Retrieve the response from the server and get the response stream. webResponse = (HttpWebResponse)webRequest.GetResponse(); responseStream = webResponse.GetResponseStream(); // Cache data in memory. downloadCache = new MemoryStream(this.MaxCacheSize); byte[] downloadBuffer = new byte[this.BufferSize]; int bytesSize = 0; int cachedSize = 0; int receivedBufferCount = 0; // Download the file until the download is paused, canceled or completed. while (true) { // Read a buffer of data from the stream. bytesSize = responseStream.Read(downloadBuffer, 0, downloadBuffer.Length); // If the cache is full, or the download is paused, canceled or // completed, write the data in cache to local file. if (this.Status != HttpDownloadClientStatus.Downloading || bytesSize == 0 || this.MaxCacheSize < cachedSize + bytesSize) { try { // Write the data in cache to local file. WriteCacheToFile(downloadCache, cachedSize); this.DownloadedSize += cachedSize; // Stop downloading the file if the download is paused, // canceled or completed. if (this.Status != HttpDownloadClientStatus.Downloading || bytesSize == 0) { break; } // Reset cache. downloadCache.Seek(0, SeekOrigin.Begin); cachedSize = 0; } catch (Exception ex) { // Fire the DownloadCompleted event with the error. this.OnDownloadCompleted(new HttpDownloadCompletedEventArgs( this.DownloadedSize, this.TotalSize, this.TotalUsedTime, ex)); return; } } // Write the data from the buffer to the cache in memory. downloadCache.Write(downloadBuffer, 0, bytesSize); cachedSize += bytesSize; receivedBufferCount++; // Fire the DownloadProgressChanged event. if (receivedBufferCount == this.BufferCountPerNotification) { InternalDownloadProgressChanged(cachedSize); receivedBufferCount = 0; } } // Update the used time when the current doanload is stopped. usedTime = usedTime.Add(DateTime.Now - lastStartTime); // Update the status of the client. Above loop will be stopped when the // status of the client is pausing, canceling or completed. if (this.Status == HttpDownloadClientStatus.Pausing) { this.Status = HttpDownloadClientStatus.Paused; } else if (this.Status == HttpDownloadClientStatus.Canceling) { this.Status = HttpDownloadClientStatus.Canceled; Exception ex = new Exception("Downloading is canceled by user's request. "); this.OnDownloadCompleted(new HttpDownloadCompletedEventArgs( this.DownloadedSize, this.TotalSize, this.TotalUsedTime, ex)); } else { this.Status = HttpDownloadClientStatus.Completed; this.OnDownloadCompleted(new HttpDownloadCompletedEventArgs( this.DownloadedSize, this.TotalSize, this.TotalUsedTime, null)); return; } } finally { // When the above code has ended, close the streams. if (responseStream != null) { responseStream.Close(); } if (webResponse != null) { webResponse.Close(); } if (downloadCache != null) { downloadCache.Close(); } } }
public void CheckUrl(out string fileName) { fileName = string.Empty; // The file could be checked only in Idle status. if (this.status != HttpDownloadClientStatus.Idle) { throw new ApplicationException( "The file could be checked only in Idle status."); } // Check the file information on the remote server. var webRequest = (HttpWebRequest)WebRequest.Create(Url); webRequest.Credentials = CredentialCache.DefaultCredentials; using (var response = webRequest.GetResponse()) { foreach (var header in response.Headers.AllKeys) { if (header.Equals("Accept-Ranges", StringComparison.OrdinalIgnoreCase)) { this.IsRangeSupported = true; } if (header.Equals("Content-Disposition", StringComparison.OrdinalIgnoreCase)) { string contentDisposition = response.Headers[header]; string pattern = ".[^;]*;\\s+filename=\"(?<file>.*)\""; Regex r = new Regex(pattern); Match m = r.Match(contentDisposition); if (m.Success) { fileName = m.Groups["file"].Value; } } } this.TotalSize = response.ContentLength; if (TotalSize <= 0) { throw new ApplicationException( "The file to download does not exist!"); } if (!IsRangeSupported) { this.StartPoint = 0; this.EndPoint = int.MaxValue; } } if (this.IsRangeSupported && (this.StartPoint != 0 || this.EndPoint != int.MaxValue)) { webRequest = (HttpWebRequest)WebRequest.Create(Url); if (EndPoint != int.MaxValue) { webRequest.AddRange(StartPoint, EndPoint); } else { webRequest.AddRange(StartPoint); } using (var response = webRequest.GetResponse()) { this.TotalSize = response.ContentLength; } } // Set the checked status. this.Status = HttpDownloadClientStatus.Checked; }
/// <summary> /// 通过HttpWebRequest线程来下载数据.它会从响应流中读取一个字节的缓冲区, /// 并把它先储存在一个MemoryStream的缓存中。 /// 如果缓存没有空间或者下载暂停、取消或完成了,就将缓存中的数据写入本地文件中。 /// </summary> void Download() { HttpWebRequest webRequest = null; HttpWebResponse webResponse = null; Stream responseStream = null; MemoryStream downloadCache = null; lastStartTime = DateTime.Now; // 设定状态. this.Status = HttpDownloadClientStatus.Downloading; try { // 为需要下载的文件创建一个请求. webRequest = (HttpWebRequest)WebRequest.Create(Url); webRequest.Method = "GET"; webRequest.Credentials = CredentialCache.DefaultCredentials; // 指定块下载 if (EndPoint != int.MaxValue) { webRequest.AddRange(StartPoint + DownloadedSize, EndPoint); } else { webRequest.AddRange(StartPoint + DownloadedSize); } // 接受服务器端的响应并得到响应流. webResponse = (HttpWebResponse)webRequest.GetResponse(); responseStream = webResponse.GetResponseStream(); // 内存中的缓存数据. downloadCache = new MemoryStream(this.MaxCacheSize); byte[] downloadBuffer = new byte[this.BufferSize]; int bytesSize = 0; int cachedSize = 0; int receivedBufferCount = 0; // 下载文件直到下载被暂停、取消或完成. while (true) { // 从流中读取缓冲区的数据. bytesSize = responseStream.Read(downloadBuffer, 0, downloadBuffer.Length); // 如果缓存是满的,或者下载被暂停、取消或完成, // 就把缓存中的数据写入本地文件. if (this.Status != HttpDownloadClientStatus.Downloading || bytesSize == 0 || this.MaxCacheSize < cachedSize + bytesSize) { try { // 把缓存中的数据写入本地文件. WriteCacheToFile(downloadCache, cachedSize); this.DownloadedSize += cachedSize; // 如果下载被暂停、取消或完成了, // 就停止下载文件. if (this.Status != HttpDownloadClientStatus.Downloading || bytesSize == 0) { break; } // 读取缓存. downloadCache.Seek(0, SeekOrigin.Begin); cachedSize = 0; } catch (Exception ex) { // 如果错误,触发DownloadCompleted事件. this.OnDownloadCompleted(new HttpDownloadCompletedEventArgs( this.DownloadedSize, this.TotalSize, this.TotalUsedTime, ex)); return; } } // 将数据从缓冲区写入内存的缓存中. downloadCache.Write(downloadBuffer, 0, bytesSize); cachedSize += bytesSize; receivedBufferCount++; // 触发DownloadProgressChanged事件. if (receivedBufferCount == this.BufferCountPerNotification) { InternalDownloadProgressChanged(cachedSize); receivedBufferCount = 0; } } // 如果当前下载被停止了,更新所用的时间. usedTime = usedTime.Add(DateTime.Now - lastStartTime); // 更新客户端的状态. 在客户端的状态为暂停、取消或完成时, // 以上的循环将被终止. if (this.Status == HttpDownloadClientStatus.Pausing) { this.Status = HttpDownloadClientStatus.Paused; } else if (this.Status == HttpDownloadClientStatus.Canceling) { this.Status = HttpDownloadClientStatus.Canceled; Exception ex = new Exception("由于用户的需求下载已被取消. "); this.OnDownloadCompleted(new HttpDownloadCompletedEventArgs( this.DownloadedSize, this.TotalSize, this.TotalUsedTime, ex)); } else { this.Status = HttpDownloadClientStatus.Completed; this.OnDownloadCompleted(new HttpDownloadCompletedEventArgs( this.DownloadedSize, this.TotalSize, this.TotalUsedTime, null)); return; } } finally { // 当以上的代码执行完毕,关闭流. if (responseStream != null) { responseStream.Close(); } if (webResponse != null) { webResponse.Close(); } if (downloadCache != null) { downloadCache.Close(); } } }
/// <summary> /// Pause the download. /// </summary> public void Pause() { // Only downloading client can be paused. if (this.Status != HttpDownloadClientStatus.Downloading) { throw new ApplicationException("Only downloading client can be paused."); } // The backgound thread will check the status. If it is Pausing, the download // will be paused and the status will be changed to Paused. this.Status = HttpDownloadClientStatus.Pausing; }
public void CheckUrl(out string fileName) { fileName = string.Empty; // The file could be checked only in Idle status. if (this.status != HttpDownloadClientStatus.Idle) { throw new ApplicationException( "The file could be checked only in Idle status."); } // Check the file information on the remote server. var webRequest = (HttpWebRequest)WebRequest.Create(Url); webRequest.Credentials = CredentialCache.DefaultCredentials; using (var response = webRequest.GetResponse()) { foreach (var header in response.Headers.AllKeys) { if (header.Equals("Accept-Ranges", StringComparison.OrdinalIgnoreCase)) { this.IsRangeSupported = true; } if (header.Equals("Content-Disposition", StringComparison.OrdinalIgnoreCase)) { string contentDisposition = response.Headers[header]; string pattern = ".[^;]*;\\s+filename=\"(?<file>.*)\""; Regex r = new Regex(pattern); Match m = r.Match(contentDisposition); if (m.Success) { fileName = m.Groups["file"].Value; } } } this.TotalSize = response.ContentLength; if (TotalSize <= 0) { throw new ApplicationException( "The file to download does not exist!"); } if (!IsRangeSupported) { this.StartPoint = 0; this.EndPoint = int.MaxValue; } } if (this.IsRangeSupported && (this.StartPoint != 0 || this.EndPoint != int.MaxValue)) { webRequest = (HttpWebRequest)WebRequest.Create(Url); if (EndPoint != int.MaxValue) { webRequest.AddRange(StartPoint, EndPoint); } else { webRequest.AddRange(StartPoint); } using (var response = webRequest.GetResponse()) { this.TotalSize = response.ContentLength; } } // Set the checked status. this.Status = HttpDownloadClientStatus.Checked; }
public HttpDownloadClient(string url, int startPoint, int endPoint, int bufferSize, int cacheSize, int bufferCountPerNotification) { if (startPoint < 0) { throw new ArgumentOutOfRangeException( "StartPoint cannot be less then 0. "); } if (endPoint < startPoint) { throw new ArgumentOutOfRangeException( "EndPoint cannot be less then StartPoint "); } if (bufferSize < 0) { throw new ArgumentOutOfRangeException( "BufferSize cannot be less then 0. "); } if (cacheSize < bufferSize) { throw new ArgumentOutOfRangeException( "MaxCacheSize cannot be less then BufferSize "); } if (bufferCountPerNotification <= 0) { throw new ArgumentOutOfRangeException( "BufferCountPerNotification cannot be less then 0. "); } this.StartPoint = startPoint; this.EndPoint = endPoint; this.BufferSize = bufferSize; this.MaxCacheSize = cacheSize; this.BufferCountPerNotification = bufferCountPerNotification; this.Url = new Uri(url, UriKind.Absolute); // Set the idle status. this.status = HttpDownloadClientStatus.Idle; }
public HttpDownloadClient(Uri url, string downloadPath, long startPoint, long endPoint, int bufferSize, int cacheSize) { if (startPoint < 0) { throw new ArgumentOutOfRangeException( "StartPoint cannot be less than 0. "); } if (endPoint < startPoint) { throw new ArgumentOutOfRangeException( "EndPoint cannot be less than StartPoint "); } if (bufferSize < 0) { throw new ArgumentOutOfRangeException( "BufferSize cannot be less than 0. "); } if (cacheSize < bufferSize) { throw new ArgumentOutOfRangeException( "MaxCacheSize cannot be less than BufferSize "); } this.StartPoint = startPoint; this.EndPoint = endPoint; this.BufferSize = bufferSize; this.MaxCacheSize = cacheSize; this.Url = url; this.DownloadPath = downloadPath; // Set the idle status. this.status = HttpDownloadClientStatus.Idle; }
public HttpDownloadClient(string url, string downloadPath, int startPoint, int endPoint, int bufferSize, int cacheSize, int bufferCountPerNotification) { if (startPoint < 0) { throw new ArgumentOutOfRangeException( "StartPoint不能小于0."); } if (endPoint < startPoint) { throw new ArgumentOutOfRangeException( "EndPoint不能小于StartPoint. "); } if (bufferSize < 0) { throw new ArgumentOutOfRangeException( "BufferSize不能小于0."); } if (cacheSize < bufferSize) { throw new ArgumentOutOfRangeException( "MaxCacheSize不能小于BufferSize."); } if (bufferCountPerNotification <= 0) { throw new ArgumentOutOfRangeException( "BufferCountPerNotification不能小于0. "); } this.StartPoint = startPoint; this.EndPoint = endPoint; this.BufferSize = bufferSize; this.MaxCacheSize = cacheSize; this.BufferCountPerNotification = bufferCountPerNotification; this.Url = new Uri(url, UriKind.Absolute); this.DownloadPath = downloadPath; // 设定空闲的状态 this.status = HttpDownloadClientStatus.Idle; }
/// <summary> /// Download the data using HttpWebRequest. It will read a buffer of bytes from the /// response stream, and store the buffer to a MemoryStream cache first. /// If the cache is full, or the download is paused, canceled or completed, write /// the data in cache to local file. /// </summary> void Download() { HttpWebRequest webRequest = null; HttpWebResponse webResponse = null; Stream responseStream = null; MemoryStream downloadCache = null; lastStartTime = DateTime.Now; // Set the status. this.Status = HttpDownloadClientStatus.Downloading; try { // Create a request to the file to be downloaded. webRequest = (HttpWebRequest)WebRequest.Create(Url); webRequest.Method = "GET"; webRequest.Credentials = CredentialCache.DefaultCredentials; // Specify the block to download. if (EndPoint != int.MaxValue) { webRequest.AddRange(StartPoint + DownloadedSize, EndPoint); } else { webRequest.AddRange(StartPoint + DownloadedSize); } // Retrieve the response from the server and get the response stream. webResponse = (HttpWebResponse)webRequest.GetResponse(); responseStream = webResponse.GetResponseStream(); // Cache data in memory. downloadCache = new MemoryStream(this.MaxCacheSize); byte[] downloadBuffer = new byte[this.BufferSize]; int bytesSize = 0; int cachedSize = 0; int receivedBufferCount = 0; // Download the file until the download is paused, canceled or completed. while (true) { // Read a buffer of data from the stream. bytesSize = responseStream.Read(downloadBuffer, 0, downloadBuffer.Length); // If the cache is full, or the download is paused, canceled or // completed, write the data in cache to local file. if (this.Status != HttpDownloadClientStatus.Downloading || bytesSize == 0 || this.MaxCacheSize < cachedSize + bytesSize) { try { // Write the data in cache to local file. WriteCacheToFile(downloadCache, cachedSize); this.DownloadedSize += cachedSize; // Stop downloading the file if the download is paused, // canceled or completed. if (this.Status != HttpDownloadClientStatus.Downloading || bytesSize == 0) { break; } // Reset cache. downloadCache.Seek(0, SeekOrigin.Begin); cachedSize = 0; } catch (Exception ex) { // Fire the DownloadCompleted event with the error. this.OnDownloadCompleted(new HttpDownloadCompletedEventArgs( this.DownloadedSize, this.TotalSize, this.TotalUsedTime, ex)); return; } } // Write the data from the buffer to the cache in memory. downloadCache.Write(downloadBuffer, 0, bytesSize); cachedSize += bytesSize; receivedBufferCount++; // Fire the DownloadProgressChanged event. if (receivedBufferCount == this.BufferCountPerNotification) { InternalDownloadProgressChanged(cachedSize); receivedBufferCount = 0; } } // Update the used time when the current doanload is stopped. usedTime = usedTime.Add(DateTime.Now - lastStartTime); // Update the status of the client. Above loop will be stopped when the // status of the client is pausing, canceling or completed. if (this.Status == HttpDownloadClientStatus.Pausing) { this.Status = HttpDownloadClientStatus.Paused; } else if (this.Status == HttpDownloadClientStatus.Canceling) { this.Status = HttpDownloadClientStatus.Canceled; Exception ex = new Exception("Downloading is canceled by user's request. "); this.OnDownloadCompleted(new HttpDownloadCompletedEventArgs( this.DownloadedSize, this.TotalSize, this.TotalUsedTime, ex)); } else { this.Status = HttpDownloadClientStatus.Completed; this.OnDownloadCompleted(new HttpDownloadCompletedEventArgs( this.DownloadedSize, this.TotalSize, this.TotalUsedTime, null)); return; } } finally { // When the above code has ended, close the streams. if (responseStream != null) { responseStream.Close(); } if (webResponse != null) { webResponse.Close(); } if (downloadCache != null) { downloadCache.Close(); } } }