How to download multiple files in C# using Parallel
By FoxLearn 7/19/2024 2:41:00 AM 8.24K
Creating a new Windows Forms application project, then drag and drop the ProgressBar, RichTextBox, Label and Button controls from the Visual Studio toolbox to your winform. You can 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.
To download multiple files in C# using Parallel
, you can utilize Parallel.ForEach
to distribute the download tasks across multiple threads.
public class SiteDownload { public static List<string> Sites() { // List of file URLs to download 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.