使用c#并行下载多个文件

我想用C#并行下载文件。 为此,我编写了这个代码,它运行得很好,但问题是UI很冷。

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 { ///  /// Interaction logic for MainWindow.xaml ///  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 "(?.*)"; } 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); } } } 

您可以将async/await与新的WebClient方法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 urlList) { foreach (var url in urlList) { await DownloadFile(url); } } 

而不是使用client.DownloadFile使用client.DownloadFileAsync这样

 var webClient=new WebClient(); webClient.DownloadFileCompleted += webClient_DownloadFileCompleted; webClient.DownloadFileAsync("Your url","file_name"); 

事件

  private void webClient_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e) { MessageBox.Show("Download Completed."); } 

用以下方法重新使用您的DownloadPfunction:

 public async void DownloadP(string[] urls) { await Task.Factory.StartNew(() => Parallel.ForEach(urls.ToList(), new ParallelOptions { MaxDegreeOfParallelism = 10 }, DownloadFile)); }