I want to download files in parallel using C#. For this, I have written this code which is working perfectly but the problem is that UI is freezing.
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Threading;
namespace FileDownloader
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
private static int count = 1;
private static string f= "lecture";
private string URL = "www.someexample.com";
public MainWindow()
{
InitializeComponent();
}
public static string GetDirectoryListingRegexForUrl(string url)
{
if (url.Equals(URL))
{
return "<a href=\".*\">(?<name>.*)</a>";
}
throw new NotSupportedException();
}
public void DownloadP(string[] urls)
{
Parallel.ForEach(urls.ToList(), new ParallelOptions { MaxDegreeOfParallelism = 10 }, DownloadFile);
}
private void DownloadFile(string url)
{
using(WebClient client=new WebClient())
{
if (url.EndsWith(".pdf"))
{
int nextIndex = Interlocked.Increment(ref count);
client.DownloadFile(url, f + nextIndex + ".pdf");
this.Dispatcher.Invoke(() => {
listbox.Items.Add(url);
});
}
}
}
private void Button_Click(object sender, RoutedEventArgs e)
{
DownloadP(listofFiles);
}
}
}
You can use async/await
with conjunction with new WebClient
method DownloadFileTaskAsync
.
private async Task DownloadFile(string url)
{
if (!url.EndsWith(".pdf"))
{
return;
}
using (var client = new WebClient())
{
int nextIndex = Interlocked.Increment(ref count);
await client.DownloadFileTaskAsync(url, "lecture" + nextIndex + ".pdf");
listBox.Items.Add(url);
}
}
private async void Button_OnClick(object sender, RoutedEventArgs e)
{
button.IsEnabled = false;
await DownloadFiles(urlList);
button.IsEnabled = true;
}
private async Task DownloadFiles(IEnumerable<string> urlList)
{
foreach (var url in urlList)
{
await DownloadFile(url);
}
}
Relace your DownloadP function with this :
public async Task DownloadP(string[] urls)
{
await Task.Factory.StartNew(() => Parallel.ForEach(urls.ToList(), new ParallelOptions { MaxDegreeOfParallelism = 10 }, DownloadFile));
}
instead of using client.DownloadFile use client.DownloadFileAsync like this
var webClient=new WebClient();
webClient.DownloadFileCompleted += webClient_DownloadFileCompleted;
webClient.DownloadFileAsync("Your url","file_name");
the event
private void webClient_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e)
{
MessageBox.Show("Download Completed.");
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With