void DownloadInternal(object obj)
{
if (this.Status != DownloadStatus.Waiting)
{
return;
}
HttpWebRequest webRequest = null;
HttpWebResponse webResponse = null;
Stream responseStream = null;
MemoryStream downloadCache = null;
this.lastStartTime = DateTime.Now;
try
{
if (!HasChecked)
{
string filename = string.Empty;
CheckUrlAndFile(out filename);
}
this.EnsurePropertyValid();
// Set the status.
this.Status = DownloadStatus.Downloading;
// Create a request to the file to be downloaded.
webRequest = DownloaderHelper.InitializeHttpWebRequest(this);
// 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;
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 != DownloadStatus.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 != DownloadStatus.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 DownloadCompletedEventArgs(
null,
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 == DownloadStatus.Pausing)
{
this.Status = DownloadStatus.Paused;
}
else if (this.Status == DownloadStatus.Canceling)
{
this.Status = DownloadStatus.Canceled;
}
else
{
this.Status = DownloadStatus.Completed;
return;
}
}
catch (Exception ex)
{
// Fire the DownloadCompleted event with the error.
this.OnDownloadCompleted(
new DownloadCompletedEventArgs(
null,
this.DownloadedSize,
this.TotalSize,
this.TotalUsedTime,
ex));
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();
}
}
}