namespace DownloadApi.Net { #region [ Using Directives ] using System; using System.Collections.Generic; using System.Text; using System.ComponentModel; using System.Net; using System.IO; #endregion public class DownloadClient { #region [ Events ] public event EventHandler Complete; public event EventHandler Cancelled; public event EventHandler ProgressChanged; public class ProgressChangedEventArgs : EventArgs { #region [ Properties ] private Int32 _Progress; public Int32 Progress { get { return _Progress; } set { _Progress = value; } } #endregion #region [ Constructor ] public ProgressChangedEventArgs(Int32 progress) { this.Progress = progress; } #endregion } #endregion #region [ Field ] private BackgroundWorker _backgroundWorker = null; #endregion #region [ Constructor ] public DownloadClient() { } #endregion #region [ Methods ] public void Start(String url, String path, Int32 startPoint) { List arguments = new List(); arguments.Add(url); arguments.Add(path); arguments.Add(startPoint); _backgroundWorker = CreateWorker(); _backgroundWorker.RunWorkerAsync(arguments); } public void Cancel() { _backgroundWorker.CancelAsync(); } private void DoWork(Object sender, DoWorkEventArgs e) { List arguments = (List)e.Argument; HttpWebRequest req = null; HttpWebResponse res = null; Stream resStream = null; Stream localStream = null; try { req = (HttpWebRequest)WebRequest.Create((String)arguments[0]); req.ContentType = "Application"; req.AddRange((Int32)arguments[1]); req.Credentials = CredentialCache.DefaultCredentials; res = (HttpWebResponse)req.GetResponse(); Int64 fileSize = res.ContentLength; resStream = res.GetResponseStream(); if ((Int32)arguments[2] == 0) localStream = new FileStream((String)arguments[1], FileMode.Create, FileAccess.Write, FileShare.None); else localStream = new FileStream((String)arguments[1], FileMode.Append, FileAccess.Write, FileShare.None); int bytesSize = 0; byte[] downBuffer = new byte[2048]; while ((bytesSize = resStream.Read(downBuffer, 0, downBuffer.Length)) > 0) { localStream.Write(downBuffer, 0, bytesSize); _backgroundWorker.ReportProgress(Convert.ToInt32((localStream.Length * 100) / fileSize + (Int32)arguments[2])); if (_backgroundWorker.CancellationPending) { e.Cancel = true; break; } } } catch { throw; } finally { if (null != req) req = null; if (null != res) res.Close(); if (null != resStream) resStream.Close(); if (null != localStream) localStream.Close(); } } private void WorkerProgressChanged(Object sender, System.ComponentModel.ProgressChangedEventArgs e) { OnProgressChanged(e.ProgressPercentage); } private void WorkerCompleted(Object sender, RunWorkerCompletedEventArgs e) { if (null != e.Error) throw new Exception("Operation cancelled!", e.Error); if (e.Cancelled) OnCancelled(); else OnComplete(); } #endregion #region [ Helper Methods ] private void OnProgressChanged(Int32 progress) { EventHandler copy = ProgressChanged; if (null != copy) copy(this, new ProgressChangedEventArgs(progress)); } private void OnComplete() { EventHandler copy = Complete; if (null != copy) copy(this, EventArgs.Empty); } private void OnCancelled() { EventHandler copy = Cancelled; if (null != copy) copy(this, EventArgs.Empty); } public BackgroundWorker CreateWorker() { BackgroundWorker bg = new BackgroundWorker(); bg.WorkerReportsProgress = true; bg.WorkerSupportsCancellation = true; bg.DoWork += DoWork; bg.ProgressChanged += WorkerProgressChanged; bg.RunWorkerCompleted += WorkerCompleted; return bg; } #endregion } }