- [SQLSERVER] Loại bỏ Restricted User trên database MSSQL
- [C#] Hướng dẫn tạo mã QRcode Style trên winform
- [C#] Hướng dẫn sử dụng temp mail service api trên winform
- [C#] Hướng dẫn tạo mã thanh toán VietQR Pay không sử dụng API trên winform
- [C#] Hướng Dẫn Tạo Windows Service Đơn Giản Bằng Topshelf
- [C#] Chia sẻ source code đọc dữ liệu từ Google Sheet trên winform
- [C#] Chia sẻ source code tạo mã QR MOMO đa năng Winform
- [C#] Chia sẻ source code phần mềm lên lịch tự động chạy ứng dụng Scheduler Task Winform
- [Phần mềm] Tải và cài đặt phần mềm Sublime Text 4180 full version
- [C#] Hướng dẫn download file từ Minio Server Winform
- [C#] Hướng dẫn đăng nhập zalo login sử dụng API v4 trên winform
- [SOFTWARE] Phần mềm gởi tin nhắn Zalo Marketing Pro giá rẻ mềm nhất thị trường
- [C#] Việt hóa Text Button trên MessageBox Dialog Winform
- [DEVEXPRESS] Chia sẻ code các tạo report in nhiều hóa đơn trên XtraReport C#
- [POWER AUTOMATE] Hướng dẫn gởi tin nhắn zalo từ file Excel - No code
- [C#] Chia sẻ code lock và unlock user trong domain Window
- [DEVEXPRESS] Vẽ Biểu Đồ Stock Chứng Khoán - Công Cụ Thiết Yếu Cho Nhà Đầu Tư trên Winform
- [C#] Hướng dẫn bảo mật ứng dụng 2FA (Multi-factor Authentication) trên Winform
- [C#] Hướng dẫn convert HTML code sang PDF File trên NetCore 7 Winform
- [C#] Hướng dẫn viết ứng dụng chat với Gemini AI Google Winform
[C#] Hướng dẫn sử dụng Parallel Download trong lập trình csharp
Xin chào các bạn, bài viết hôm nay mình sẽ hướng dẫn các bạn cách sử dụng Parallel Download Website trong lập trình C#.
Trong ví dụ này, mình sẽ tải dữ liệu của 10 website và khi tải source code về xong mình sẽ count số dòng code của từng website.
Bình thường nếu các bạn tải đồng bộ (Sync) dữ liệu từ 10 website thì tốc độ tải chậm vì tải đồng bộ, và GUI của Form sẽ bị treo, các bạn sẽ không thể thao tác được.
Cách tải dữ liệu bằng Parallel nó sẽ tải dữ liệu bất đồng bộ (Async) từng website (một lần tải nhiều website cùng một lúc, và nó không làm treo form của mình).
Ví dụ: Mình có 10 website như sau.
public static List<string> PrepData()
{
List<string> output = new List<string>();
output.Add("https://laptrinhvb.net");
output.Add("https://freetuts.net");
output.Add("https://howteam.vn");
output.Add("https://vnexpress.net");
output.Add("https://24h.com.vn");
output.Add("https://dantri.com.vn");
output.Add("https://genk.vn");
output.Add("https://bongdaso.com");
output.Add("https://quantrimang.com");
output.Add("https://noithattuonglai.com.vn");
return output;
}
Giao diện download bằng Paravell có ProcessBar C#:
Như hình demo trên, các bạn thấy tốc độ tải dữ liệu của 10 website trên chỉ mất chưa đến 2 giây là đã hoàn tất.
Đầu tiên các bạn cần tạo một Model Class với tên WebsiteDataModel.cs
Class này chứa 2 thuộc tính: WebsiteURL và WebsiteData
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ParallellDownload
{
class WebsiteDataModel
{
public string WebsiteUrl { get; set; } = "";
public string WebsiteData { get; set; } = "";
}
}
Tiếp đến, các bạn tạo tiếp cho mình một class ProgressReportModel.cs
Class này sử dụng để hiển thị phần trăm progessbar đã tải dữ liệu về.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ParallellDownload
{
class ProgressReportModel
{
public int PercentageComplete { get; set; } = 0;
public List<WebsiteDataModel> SitesDownloaded { get; set; } = new List<WebsiteDataModel>();
}
}
Tiếp theo, các bạn tạo tiếp một class với tên DemoMethod.cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace ParallellDownload
{
static class DownloadMethods
{
public static List<string> PrepData()
{
List<string> output = new List<string>();
output.Add("https://laptrinhvb.net");
output.Add("https://freetuts.net");
output.Add("https://howkteam.vn");
output.Add("https://vnexpress.net");
output.Add("https://24h.com.vn");
output.Add("https://dantri.com.vn");
output.Add("https://genk.vn");
output.Add("http://bongdaso.com");
output.Add("https://quantrimang.com");
output.Add("https://noithattuonglai.com.vn");
return output;
}
public static async Task<List<WebsiteDataModel>> RunDownloadParallelAsyncV2(IProgress<ProgressReportModel> progress, CancellationTokenSource cts)
{
List<string> websites = PrepData();
List<WebsiteDataModel> output = new List<WebsiteDataModel>();
ProgressReportModel report = new ProgressReportModel();
ParallelOptions po = new ParallelOptions();
po.MaxDegreeOfParallelism = 8;
po.CancellationToken = cts.Token;
await Task.Run(() =>
{
try
{
Parallel.ForEach<string>(websites, po, (site) =>
{
WebsiteDataModel results = DownloadWebsite(site);
output.Add(results);
report.SitesDownloaded = output;
report.PercentageComplete = (output.Count * 100) / websites.Count;
progress.Report(report);
po.CancellationToken.ThrowIfCancellationRequested();
});
}
catch (OperationCanceledException e)
{
Console.WriteLine(e.Message);
}
finally
{
//cts.Dispose();
}
});
return output;
}
private static WebsiteDataModel DownloadWebsite(string websiteURL)
{
WebsiteDataModel output = new WebsiteDataModel();
WebClient client = new WebClient();
output.WebsiteUrl = websiteURL;
output.WebsiteData = client.DownloadString(websiteURL);
return output;
}
}
}
Và tiếp theo là viết hàm cho nút Download Parallel và nút dừng tải thông qua sử dụng Token.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace ParallellDownload
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
CancellationTokenSource cts;
private void PrintResults(List<WebsiteDataModel> results)
{
rtf_result.Text = "";
foreach (var item in results)
{
rtf_result.Text += $"{ item.WebsiteUrl } downloaded: { item.WebsiteData.Length } characters long.{ Environment.NewLine }";
}
}
private void ReportProgress(object sender, ProgressReportModel e)
{
progressBar.Value = e.PercentageComplete;
lbl_percent.Text = e.PercentageComplete.ToString() + "%";
PrintResults(e.SitesDownloaded);
}
private async void btn_download_Click(object sender, EventArgs e)
{
cts = new CancellationTokenSource();
Progress<ProgressReportModel> progress = new Progress<ProgressReportModel>();
progress.ProgressChanged += ReportProgress;
var watch = System.Diagnostics.Stopwatch.StartNew();
var results = await DownloadMethods.RunDownloadParallelAsyncV2(progress, cts);
PrintResults(results);
watch.Stop();
var elapsedMs = watch.ElapsedMilliseconds;
rtf_result.Text += $"Total execution time: { elapsedMs }";
}
private void btn_stop_Click(object sender, EventArgs e)
{
cts.Cancel();
}
}
}
Hy vọng bài viết sẽ giúp ích được cho các bạn về cách sử dụng bất đồng bộ trong C#.
Thanks For Watching!