Creating a new windows forms application project, you need to drag the ProgressBar, RichTextBox, Label and Button controls from the visual studio toolbox to your winform, then design a simple UI that allows you to download multiple files through multiple threads as shown below.

Create a Website class to map data return from the site that you want to download data.
public class Website
{
public string Url { get; set; }
public string Data { get; set; }
}
Create a ProgressReport class to update your percentage download to the progress bar control.
public class ProgressReport
{
public int PercentageComplete { get; set; }
public List<Website> SitesDownloaded { get; set; }
}
Create a SiteDownload class to help you download the list of website that you initialize.
public class SiteDownload
{
public static List<string> Sites()
{
List<string> list = new List<string>();
list.Add("http://foxlearn.com");
list.Add("http://c-sharpcode.com");
list.Add("http://ebook-dl.net");
return list;
}
public static async Task<List<Website>> ParallelDownload(IProgress<ProgressReport> progress, CancellationTokenSource cancellationTokenSource)
{
List<string> sites = Sites();
List<Website> list = new List<Website>();
ProgressReport progressReport = new ProgressReport();
ParallelOptions parallelOptions = new ParallelOptions();
parallelOptions.MaxDegreeOfParallelism = 8;
parallelOptions.CancellationToken = cancellationTokenSource.Token;
await Task.Run(() =>
{
try
{
Parallel.ForEach<string>(sites, parallelOptions, (site) =>
{
Website results = Download(site);
list.Add(results);
progressReport.SitesDownloaded = list;
progressReport.PercentageComplete = (list.Count * 100) / sites.Count;
progress.Report(progressReport);
parallelOptions.CancellationToken.ThrowIfCancellationRequested();
});
}
catch (OperationCanceledException ex)
{
throw ex;
}
});
return list;
}
private static Website Download(string url)
{
Website website = new Website();
WebClient client = new WebClient();
website.Url = url;
website.Data = client.DownloadString(url);
return website;
}
}
You can get the list of site data that you want to download. Using async parallel c# helps your program run faster, it will create multiple threads based on the number of CPU cores.
We will write c# code run multiple tasks in parallel, you can do the same way with download multiple images from url c# or download file from url to folder.
A faster way to download multiple files or images based on url is to use parallel to create multiple threads, which increases high performance file download that constraining concurrent threads in c#.
Next, Add code to handle your winform as shown below.
Create the PrintResults method allows you to display the download file information into the RichTextBox control.
void PrintResults(List<Website> results)
{
richTextBox1.Text = string.Empty;
foreach (var item in results)
richTextBox1.Text += $"{ item.Url } downloaded: { item.Data.Length } characters long.{ Environment.NewLine }";
}
Create the ReportProgress method allows you to upload the progress bar and label controls, then call the PrintResults method to display the dowload file information.
void ReportProgress(object sender, ProgressReport e)
{
progressBar1.Value = e.PercentageComplete;
lblPercent.Text = $"Completed: {e.PercentageComplete} %";
PrintResults(e.SitesDownloaded);
}
Add the click event handler to the Download button that lets you handle the download file.
CancellationTokenSource cancellationTokenSource;
private async void btnDownload_Click(object sender, EventArgs e)
{
try
{
cancellationTokenSource = new CancellationTokenSource();
Progress<ProgressReport> progress = new Progress<ProgressReport>();
progress.ProgressChanged += ReportProgress;
var watch = Stopwatch.StartNew();
var results = await SiteDownload.ParallelDownload(progress, cancellationTokenSource);
PrintResults(results);
watch.Stop();
var elapsed = watch.ElapsedMilliseconds;
richTextBox1.Text += $"Total execution time: { elapsed }";
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Message", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
finally
{
cancellationTokenSource.Dispose();
}
}
And don't forget to add the click event handler to the Stop button allows you to cancel download file.
private void btnStop_Click(object sender, EventArgs e)
{
if (cancellationTokenSource != null)
cancellationTokenSource.Cancel();
}
The Stopwatch class has methods and properties that you can use to accurately measure elapsed time.
A Stopwatch instance can measure the time that has elapsed over a period of time or the total amount of time that has elapsed in many time periods.