Download a file in the background!
2
Shows how to download a file using the BackgroundWorker Pattern in C# with the .net 2.0 framework. Next will be a wrapper that harnesses this object to create a multi-segmented file downloading manager utility!
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<ProgressChangedEventArgs> 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<Object> arguments = new List<Object>();
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<Object> arguments = (List<Object>)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<ProgressChangedEventArgs> 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
}
}





All criticism is accepted!
Is there any available so far??
Thanks for the help..
Regards