Click here to Skip to main content
Licence 
First Posted 14 Jan 2007
Views 43,808
Downloads 1,131
Bookmarked 89 times

Downloader Component

By | 14 Jan 2007 | Article
A component to download files over the network with support for proxies, SSL and resume.
Sample Image - Downloader.jpg

Introduction

Downloading files over the network could be a cumbersome task. Trying to implement other features like auto-resume and support for proxy servers, etc. makes it even harder. Using this component can make things a lot easier for yourself. You can download files over proxies, password protected sites or untrusted SSL connections simply by setting a few properties. The example that is provided shows how to do the job and how to handle events over a simple GUI.

Since the download operation takes place in a worker thread asynchronously, you don't need to worry about downloading large files or blocking the user interface. There are some points you need to have in mind though.

Aborting the Worker Thread

Stopping a download operation that is running is tricky. You could just call the DownloadThread.Abort() method on the downloader thread to stop the work, but this is not the recommended way. The main reason for this is that Thread.Abort throws an exception which can occur at any time during your work and leaves your running state inconsistent. The easier way is to check for a boolean field, and terminate the operation when the field is set, or run the job on an entirely different process. To read more about this idea, check Ian Griffiths blog post here.

Updating GUI

When running a download job, the Downloader component provides its internal progress and error state through events and custom eventargs. Since the eventargs are constructed on the worker thread, trying to update the user-interface from the worker thread throws a Cross-Thread exception. The workaround to update the user interface is to use the Invoke method (inherited from Control), a Delegate and call to the necessary method(s), like this:

private delegate void ParamMethodInvoker
    (long fileSize, long progressValue, string message);

/// <summary>
/// Call UpdateProgress method using a delegate and provide method parameters
/// </summary>
private void OnDownloadProgressChanged
    (object sender, DownloadProgressEventArgs e)
{
    Invoke(new ParamMethodInvoker(UpdateProgress), new object[] 
        { e.BytesRead, e.TotalBytes, e.Message });
}

/// <summary>
/// Normally update the user interface
/// </summary>
private void UpdateProgress(long bytesRead, long totalBytes, string message)
{
    int kbRead = Convert.ToInt32(bytesRead) / 1024;
    int kbTotal = Convert.ToInt32(totalBytes) / 1024;
    int percent = Convert.ToInt32((bytesRead * 100) / totalBytes);

    progress.Value = percent;
    lblDownloadMessage.Text = 
        string.Format("{0:#,###} of {1:#,###} KBytes ({2}%)", 
        kbRead, kbTotal, percent);
}

Resuming a Download

To resume a download job, we can simply continue where we left off. When restarting a download job, the downloader component first checks for the existing file at the specified location (through DownloadPath property). If the file exists, it reads the Length of the existing file and sets the HttpWebRequest's range using AddRange method. Overloads of the AddRange method could be used to handle multi-part downloading of a single file.

long startingPoint = 0;

if(File.Exists(DownloadPath))
{
    startingPoint = new FileInfo(DownloadPath).Length;
}

HttpWebRequest _Request = (HttpWebRequest)HttpWebRequest.Create(url);
_Request.AddRange(startingPoint);

Points of Interest

Implementing other features such as multi-part downloading (like download accelerator applications) and FTP downloads seems like a good idea. Any suggestions/comments/feedback are highly appreciated.

History

Version 1

  • Provided the component with base features and events
  • Provided a basic form to show features of the component

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

Hadi Eskandari

Software Developer (Senior)
SAM Enterprise
Iran (Islamic Republic Of) Iran (Islamic Republic Of)

Member

Follow on Twitter Follow on Twitter
Working on both Java and .NET Technology, I have developed various enterprise level applications on both platforms. Currently, I am working as a Senior Developer at SAM Enterprise company which resides in Tehran, Iran, and is a partner with S4M GmbH which develops solutions for media and is a Microsoft Gold Partner. I'm also a Microsoft Certified Professional Developer for Web, Windows and Enterprise applications.

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board. (secure sign-in)
 
Search this forum  
 FAQ
    Noise  Layout  Per page   
  Refresh
QuestionMy vote of 5 PinmemberPouriya.GH3:27 30 Apr '12  
GeneralMy vote of 5 PinmemberShahin Khorshidnia19:18 3 Apr '11  
GeneralError Downloading file greater than 2GB [modified] Pinmemberakshayoh8:43 12 Feb '11  
GeneralRe: Error Downloading file greater than 2GB [modified] PinmemberKOS_void4:39 28 Feb '12  
Generaldoc required Pinmemberprudhvi123459:03 16 Mar '10  
GeneralImplementing Speed Limiting (aka Throttling/Shaping) PinmemberTrendyTim16:30 14 Sep '07  
Generalpoint of interest Pinmemberjugomkd758:25 10 Aug '07  
GeneralRe: point of interest Pinmemberjugomkd7521:20 10 Aug '07  
QuestionHow about FTP ?? Pinmember_Thurein_17:09 9 May '07  
AnswerRe: How about FTP ?? Pinmemberh.eskandari19:52 9 May '07  
GeneralRe: How about FTP ?? Pinmember_Thurein_21:36 9 May '07  
GeneralRe: How about FTP ?? Pinmemberh.eskandari22:41 9 May '07  
GeneralRe: How about FTP ?? PinmemberGaara [BTK]0:28 12 Oct '07  
Questionwhat if from a webdav server Pinmemberroychoo4:11 16 Mar '07  
AnswerRe: what if from a webdav server PinmemberHadi Eskandari18:51 16 Mar '07  
GeneralTest for file size if resuming PinmemberJeffrey Scott Flesher18:14 23 Jan '07  
GeneralVery similar... PinmemberScott Dorman6:30 15 Jan '07  
GeneralRe: Very similar... PinmemberHadi Eskandari19:22 16 Jan '07  
GeneralRe: Very similar... PinmemberScott Dorman4:09 18 Jan '07  
GeneralTnx For This Article Pinmemberyunas2:36 14 Jan '07  
GeneralJust a little problem PinmemberVertyg01:34 14 Jan '07  
GeneralRe: Just a little problem PinmemberHadi Eskandari19:14 14 Jan '07  
GeneralRe: Just a little problem PinmemberHadi Eskandari20:50 11 Feb '07  
GeneralRe: Just a little problem PinmemberVertyg021:42 11 Feb '07  
GeneralRe: Just a little problem PinmemberHadi Eskandari19:39 12 Feb '07  

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Mobile
Web02 | 2.5.120517.1 | Last Updated 14 Jan 2007
Article Copyright 2007 by Hadi Eskandari
Everything else Copyright © CodeProject, 1999-2012
Terms of Use
Layout: fixed | fluid