A step by step tutorial teaching you how to create your own chat client and chat server easily in C#, for local networks or the Internet.
A C# tutorial showing you how to make use of WMI to extract information on disk drives, such as model, capacity, sectors and serial number.
This tutorial will teach you how to calculate the shipping cost based on the weight, height, length and depth of the box, the distance and the UPS service type.
Creating a download manager in C#
Learn how to create a download manager with a progress indicator in C# / .NET 2.0 using stream readers, web clients, web requests, buffers and more. You will also be learning the basics of threading in C#.
On Thursday, April 13th 2006 at 01:38 PM
By Andrew Pociu (View Profile)
(Rated 4.7 with 65 votes)
Download this project (Visual Studio 2005)
Sometime in 2004 on Geekpedia we saw a tutorial entitled Using WebClient to download a file, where we would use a few lines of code to save a file retrieved from the web through http on our hard drive. Now we're taking one step forward, to complicate the things just a little, so that we can display the progress of the download.
For displaying the progress we're going to use a ProgressBar and a Label. For calculating it, we'll need to retrieve the total size of the file from the web server, and calculate what we've downloaded by now.
This tutorial teaches you how to create a download manager in C# 2.0 (.NET Framework 2.0), using Visual Studio 2005. However, you can always convert this code to Visual Basic .NET, or to an earlier version of .NET Framework such as .NET 1.1.
Start by creating a C# Windows Application project in Visual Studio and on the form drag 3 labels, 2 textboxes, 2 buttons and one progressbar.
As you can see in the form above, the first two labels are just for describing the role of the first two textboxes which are named txtUrl and txtPath. They will obviously hold the URL of the file we want to download and the local path (and filename) to where we want to save it. The default values I set in the project will download a short video from Microsoft's Channel 9 website to C:\Filename.wmv.
The two buttons - btnDownload and btnStop - are used for starting and stopping a download, while the label below them - lblProgress - is used for showing the current progress of the download in bytes and percentage. Finally, the ProgressBar located at the bottom of the form is entitled prgDownload and it display the progress of the download on a scale from 1 to 100.
Now let's get into coding. Switch to code view, and the first thing we need to do is to add a few using statements for the namespaces we're going to use. Add the following 3 lines below the already existing using statements:
System.Net will be used for connecting to the web server, System.IO will be used for saving the file to the hard drive, and System.Threading will be used for the thread in which we're going to put the downloading process.
Inside the form's class, right above the constructor, add the following lines:
As you can see, we are creating a few objects that we're going to use later in the code. The object that stands out the most is not really an object, but a delegate: UpdateProgressCallback - this delegate will be used to call a method you'll see later in our code - UpdateProgress - from inside the thread. Because you see, from inside a thread we can't update the form elements directly (the label and the progress bar), so we need to create a delegate first, that takes the same arguments as the method. In our case the arguments are two Int64 variables that hold the number of bytes we downloaded from the server by now, and the number of total bytes the file has. Int64 is needed because this number can be really big.
Now let's review the biggest piece of the code. The one where the file actually gets downloaded. We'll put this code in a method called Download() which we're going to call in a thread when the download button is pressed. Here goes the method, below it there's more explanation of the code:
The first line inside the method mentions that inside this method we'll be using the wcDownload object, which can be disposed after we're finished. If any error happens within the code, we have a finally block which closes the streams to prevent keeping a connection opened uselessly and to prevent the local file from being locked by the code.
Inside the try block we first retrieve information about the file using HttpWebRequest and HttpWebResponse objects. Note that some servers don't give information about the size of the file, case in which we can only download blindly. If the web server did not return any information regarding the size of the file, webResponse.ContentLength will return -1.
After we get the size of the file, we define the stream that retrieves the bytes from the server, and the stream that saves the file to the hard drive. Before starting to stream the bytes down the cables, we create a buffer where we store the data that is written to the hard drive file. The buffer is 2048 bytes in size, but you can change it to a different value if you prefer.
In the while loop we loop through the buffer and write the content of the buffer to the file on the local drive. We also use the Invoke method of the form to call UpdateProgressCallback (the delegate of UpdateProgress). In the array we pass two parameters that UpdateProgress accepts: how much we downloaded until now (by measuring the length of the local stream), and how big the total file is. If you don't have any knowledge of threading in C#, you probably would have guessed that you can update the form elements (labels, progress bars, etc.) directly, but for good enough reasons you can't.
If we were to call the Download() method directly, then we wouldn't have to use this.Invoke to call the UpdateProgress method. Speaking of UpdateProgress, let's see how this method looks like:
We do a simple math calculation to get the percentage (0 to 100) and we set it on the ProgressBar to reflect the progress. We also set the label with information on the progress of the download.
We're done with the methods for this application, now we only need to create the two event handlers for the Download and Stop buttons. Double clicking btnDownload in Visual Studio 2005 will create the Click event handler for you. Use the following code:
In the code above we start a new thread, to which we pass the name of the method (without the parenthesis). Then we start the thread. The reason we need to use a thread and we can't just call the method from inside the Click event is because in that case our application would completely hang while downloading the file. It would become unusable and unresponsive, as if it crashed.
Finally, we have the code for the stop button:
To make this a real download manager, we'd have to add resume options, and a download list so that we give the user the option to download multiple files at once, or schedule them. This will be covered in a future tutorial.
Below is the entire source code of Form1.cs that you can also view in the Visual Studio 2005 project files attached to this tutorial.
You can now proceed to the second part of this tutorial, entitled Creating an advanced download manager in C#.
|Digg It! Del.icio.us Reddit StumbleIt Newsvine Furl BlinkList|
Rate this tutorial
There are no related tutorials.
Related Source Code
There is no related source code.
C# Job Search