Click here to Skip to main content
11,706,979 members (32,599 online)
Click here to Skip to main content

Downloading Files in .NET With All Information: Progressbar, Download Speed, Supports Cancel and Resume

, , 22 Apr 2009 CPOL 260.7K 21K 176
Rate this:
Please Sign up or sign in to vote.
How to download files in .NET with all information about the progess (progressbar, download speed), supports cancel and resume
Screenshot - screen.jpg

Introduction  

I'll explain how you can build a complete, reliable and powerful download manager with .NET Framework.
It is able to show a rarity of data about the download in progress, including the download speed, the file size, the downloaded size, and the percentage of completion.

A completely new class has been written based on this code, which features logic/layout abstraction, multiple file download support, and is more easy to use by providing a variety of properties and events. Check out the FileDownloader article.

The files are downloaded via the HttpWebRequest  and HttpWebResponse, and written to a file with the StreamWriter. All this is done on a separate thread (with a BackgroundWorker), so the application using this downloader won't freeze.

Using the Code 

The demo application is pretty simple, and contains only the needed UI components for downloading a file. You can of course implement this downloader in your own application, or just use it to download in the background without any user interaction.

The most important code can be found in the DoWork method of the BackgroundWorker. First, an attempt will be made to establish a connection to the file. If this is successful, a script in the Do loop will start downloading the file block by block, until there are no remaining bytes to be downloaded. Note that as soon as a block of data has been received, it's written to the local target file.

Private Sub BackgroundWorker1_DoWork(ByVal sender As System.Object, _
    ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork

        'Creating the request and getting the response
        Dim theResponse As HttpWebResponse
        Dim theRequest As HttpWebRequest
        Try 'Checks if the file exist

            theRequest = WebRequest.Create(Me.txtFileName.Text)
            theResponse = theRequest.GetResponse
        Catch ex As Exception

            MessageBox.Show("An error occurred while downloading file. _
			Possible causes:" & ControlChars.CrLf & _
                            "1) File doesn't exist" & ControlChars.CrLf & _
                            "2) Remote server error", "Error", _
			MessageBoxButtons.OK, MessageBoxIcon.Error)

            Dim cancelDelegate As New DownloadCompleteSafe(AddressOf DownloadComplete)

            Me.Invoke(cancelDelegate, True)

            Exit Sub
        End Try
        Dim length As Long = theResponse.ContentLength 'Size of the response (in bytes)

        Dim safedelegate As New ChangeTextsSafe(AddressOf ChangeTexts)
        Me.Invoke(safedelegate, length, 0, 0, 0) 'Invoke the TreadsafeDelegate

        Dim writeStream As New IO.FileStream(Me.whereToSave, IO.FileMode.Create)

        'Replacement for Stream.Position (webResponse stream doesn't support seek)
        Dim nRead As Integer

        'To calculate the download speed
        Dim speedtimer As New Stopwatch
        Dim currentspeed As Double = -1
        Dim readings As Integer = 0

        Do

            If BackgroundWorker1.CancellationPending Then 'If user aborts download
                Exit Do
            End If

            speedtimer.Start()

            Dim readBytes(4095) As Byte
            Dim bytesread As Integer = theResponse.GetResponseStream.Read_
						(readBytes, 0, 4096)

            nRead += bytesread
            Dim percent As Short = (nRead * 100) / length

            Me.Invoke(safedelegate, length, nRead, percent, currentspeed)

            If bytesread = 0 Then Exit Do

            writeStream.Write(readBytes, 0, bytesread)

            speedtimer.Stop()

            readings += 1
            If readings >= 5 Then 'For increase precision, _
			' the speed is calculated only every five cycles
                currentspeed = 20480 / (speedtimer.ElapsedMilliseconds / 1000)
                speedtimer.Reset()
                readings = 0
            End If
        Loop

        'Close the streams
        theResponse.GetResponseStream.Close()
        writeStream.Close()

        If Me.BackgroundWorker1.CancellationPending Then

            IO.File.Delete(Me.whereToSave)

            Dim cancelDelegate As New DownloadCompleteSafe(AddressOf DownloadComplete)

            Me.Invoke(cancelDelegate, True)

            Exit Sub

        End If

        Dim completeDelegate As New DownloadCompleteSafe(AddressOf DownloadComplete)

        Me.Invoke(completeDelegate, False)

End Sub

This code uses delegates to invoke methods on the main thread, and pass data about the download progress to them. 

The code does not support FTP downloads, but can be easily modified to do this.  

Resume Downloads 

It is possible to modify the code to allow resuming downloads. Add this code before the first use of the HttpWebRequest object.

theRequest.AddRange(whereYouWantToStart) '<- add this

You'll also need to set the Position property of the FileStream instance to the position where you want to resume the download. So be sure you also save this before the download is cancelled.

Dim writeStream As New IO.FileStream(Me.whereToSave, IO.FileMode.Open)
writeStream.Position = whereYouWantToStart

Calculating Speed 

The code contains built in download speed calculation, using the StopWatch class. This will return another result every time 5 packages have been downloaded. Note that you can also manually calculate the speed, and use a timer to get data at a more regular interval.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Authors

Carmine_XX
Student
Italy Italy
I'm a young Italian student from Milan.
I usually develop in Visual Basic.Net (and also C#), both Windows and Web (ASP.Net) applications.
Moreover I also know some other programming languages: PHP, HTML, SQL, VB6 and Javascript. (and a bit of C++).
All of my programming projects can be found on my website: www.thetotalsite.it.

Jeroen De Dauw
Software Developer
Belgium Belgium
I am a free and open source software enthusiast and freelance software developer with multiple years of experience in both web and desktop development. Currently my primarily focus is on MediaWiki and Semantic MediaWiki work. I'm in the all time top 10 MediaWiki comitters and am one of the WikiWorks consultants. You can contact me at jeroendedauw at gmail for development jobs and questions related to my work.

More info can be found on my website [0] and my blog [1]. You can also follow me on twitter [2] and identi.ca [3].

[0] http://www.jeroendedauw.com/
[1] http://blog.bn2vs.com/
[2] https://twitter.com/#!/JeroenDeDauw
[3] http://identi.ca/jeroendedauw

You may also be interested in...

Comments and Discussions

 
Questionhelp for FTP download Pin
robinex25-May-15 9:53
memberrobinex25-May-15 9:53 
Questioncan someone help me to modify the code to support resuming. Pin
Soumya Kanti Sar22-Apr-15 18:47
memberSoumya Kanti Sar22-Apr-15 18:47 
QuestionCan the code resume downloading the file after the app is restarted. Pin
Soumya Kanti Sar22-Apr-15 16:22
memberSoumya Kanti Sar22-Apr-15 16:22 
QuestionDownloading Big Files Pin
mustibh17-Feb-15 2:48
membermustibh17-Feb-15 2:48 
GeneralA review of the code... Pin
Tarek Ziani21-Mar-14 4:03
memberTarek Ziani21-Mar-14 4:03 
GeneralMy vote of 5 Pin
Member 1047116124-Dec-13 3:38
memberMember 1047116124-Dec-13 3:38 
QuestionActual Download Speed Pin
Gregor Vladoskiv26-Nov-13 2:21
memberGregor Vladoskiv26-Nov-13 2:21 
GeneralMy vote of 5 Pin
Viper20109-Sep-13 14:27
memberViper20109-Sep-13 14:27 
QuestionHandle Redirects Pin
Member 1023067425-Aug-13 2:23
memberMember 1023067425-Aug-13 2:23 
GeneralNo Problem with me, just need PAUSE FEATURE :( Pin
sayib25-Jul-13 6:51
membersayib25-Jul-13 6:51 
GeneralMy vote of 4 Pin
sayib25-Jul-13 6:46
membersayib25-Jul-13 6:46 
QuestionProblem with Downloading Files in .NET With All Information: Progressbar, Download Speed, Supports Cancel and Resume Pin
MarshallR24-Feb-13 22:19
memberMarshallR24-Feb-13 22:19 
AnswerRe: Problem with Downloading Files in .NET With All Information: Progressbar, Download Speed, Supports Cancel and Resume Pin
Carmine_XX26-Feb-13 0:54
memberCarmine_XX26-Feb-13 0:54 
GeneralRe: Problem with Downloading Files in .NET With All Information: Progressbar, Download Speed, Supports Cancel and Resume Pin
Member 1077775727-Apr-14 23:54
memberMember 1077775727-Apr-14 23:54 
QuestionThis demo cann't download large files with size >30MB Pin
Member 466294231-Jan-13 21:15
memberMember 466294231-Jan-13 21:15 
GeneralMy vote of 2 Pin
stingrayweb28-May-12 16:14
memberstingrayweb28-May-12 16:14 
GeneralMy vote of 5 Pin
BeeWayDev14-Feb-12 3:49
memberBeeWayDev14-Feb-12 3:49 
QuestionArithmetic operation resulted in an overflow. Pin
musabiralo15-Dec-11 14:30
membermusabiralo15-Dec-11 14:30 
AnswerRe: Arithmetic operation resulted in an overflow. Pin
Jeroen De Dauw15-Dec-11 14:47
memberJeroen De Dauw15-Dec-11 14:47 
Questionproblem with download Pin
pjsurve9-May-11 22:17
memberpjsurve9-May-11 22:17 
RantDownload a File with Progress Change VB.NET Pin
Justin Spafford8-Jan-11 9:56
memberJustin Spafford8-Jan-11 9:56 
GeneralIt not automatic get file name and file type Pin
Sting258200030-Dec-10 16:21
memberSting258200030-Dec-10 16:21 
GeneralMy vote of 5 Pin
Madhu Sasi Nair28-Oct-10 22:44
memberMadhu Sasi Nair28-Oct-10 22:44 
GeneralMy vote of 1 Pin
smartsabbas5217-Aug-10 2:09
membersmartsabbas5217-Aug-10 2:09 
GeneralProblem with download progress Pin
Passion_Knight7-Jul-10 4:19
memberPassion_Knight7-Jul-10 4:19 
GeneralRe: Problem with download progress Pin
jeroen de dauw7-Jul-10 4:21
memberjeroen de dauw7-Jul-10 4:21 
GeneralRe: Problem with download progress Pin
Passion_Knight7-Jul-10 4:22
memberPassion_Knight7-Jul-10 4:22 
GeneralRe: Problem with download progress Pin
Passion_Knight7-Jul-10 4:27
memberPassion_Knight7-Jul-10 4:27 
GeneralRe: Problem with download progress Pin
jeroen de dauw7-Jul-10 4:33
memberjeroen de dauw7-Jul-10 4:33 
GeneralRe: Problem with download progress Pin
Passion_Knight7-Jul-10 4:34
memberPassion_Knight7-Jul-10 4:34 
GeneralRe: Problem with download progress Pin
jeroen de dauw7-Jul-10 4:46
memberjeroen de dauw7-Jul-10 4:46 
GeneralRe: Problem with download progress Pin
Passion_Knight7-Jul-10 5:06
memberPassion_Knight7-Jul-10 5:06 
GeneralRe: Problem with download progress Pin
Lancer240423-Aug-10 0:54
memberLancer240423-Aug-10 0:54 
Generalneed a final documentation for this Pin
prudhvi1234516-Mar-10 8:57
memberprudhvi1234516-Mar-10 8:57 
GeneralRe: need a final documentation for this Pin
jeroen de dauw16-Mar-10 12:11
memberjeroen de dauw16-Mar-10 12:11 
GeneralRe: need a final documentation for this Pin
iJam_j6-Feb-11 18:46
memberiJam_j6-Feb-11 18:46 
GeneralProblem in re-calling Me.BackgroundWorker1.RunWorkerAsync() Pin
Demantorr14-Jan-10 8:29
memberDemantorr14-Jan-10 8:29 
GeneralRe: Problem in re-calling Me.BackgroundWorker1.RunWorkerAsync() Pin
jeroen de dauw14-Jan-10 10:08
memberjeroen de dauw14-Jan-10 10:08 
GeneralMediafire Pin
John Boshelle24-Nov-09 6:24
memberJohn Boshelle24-Nov-09 6:24 
QuestionI get the following bug if i use your code Pin
ghvnd30-Jul-09 22:42
memberghvnd30-Jul-09 22:42 
AnswerRe: I get the following bug if i use your code Pin
bn2vs31-Jul-09 7:54
memberbn2vs31-Jul-09 7:54 
GeneralPermission to use this code Pin
bn2vs18-Apr-09 1:19
memberbn2vs18-Apr-09 1:19 
GeneralRe: Permission to use this code Pin
Carmine_XX18-Apr-09 2:58
memberCarmine_XX18-Apr-09 2:58 
GeneralRe: Permission to use this code Pin
bn2vs19-Apr-09 3:47
memberbn2vs19-Apr-09 3:47 
GeneralRe: Permission to use this code Pin
Carmine_XX20-Apr-09 2:02
memberCarmine_XX20-Apr-09 2:02 
GeneralRe: Permission to use this code Pin
bn2vs21-Apr-09 1:46
memberbn2vs21-Apr-09 1:46 
GeneralRe: Permission to use this code Pin
Carmine_XX21-Apr-09 2:38
memberCarmine_XX21-Apr-09 2:38 
GeneralRe: Permission to use this code Pin
bn2vs21-Apr-09 3:12
memberbn2vs21-Apr-09 3:12 
GeneralRe: Permission to use this code Pin
bn2vs22-Apr-09 6:03
memberbn2vs22-Apr-09 6:03 
GeneralRe: Permission to use this code Pin
Carmine_XX22-Apr-09 6:26
memberCarmine_XX22-Apr-09 6:26 

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.

| Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.150819.1 | Last Updated 23 Apr 2009
Article Copyright 2007 by Carmine_XX, Jeroen De Dauw
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid