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
}
}