- [C#] Ẩn ứng dụng winform từ Apps vào Background Process trên Task Manager
- [SQLSERVER] Xử lý ngoại lệ sử dụng TRY...CATCH và RAISEERROR
- [C#] Bắt sự kiện bàn phím chuột bên ngoài ứng dụng winform sử dụng thư viện MouseKeyHook
- [DEVEXPRESS] Đặt mật khẩu và bỏ mật khẩu tập tin file PDF
- [C#] Thêm ứng dụng vào Taskbar sử dụng SharpShell DeskBand
- [C#] Hướng dẫn thêm text vào hình ảnh icon winform
- [C#] Chia sẽ tổng hợp source code đồ án về Csharp
- [C#] Hướng dẫn viết ứng dụng quay màn hình video winform, Screen Recorder
- [C#] Hướng dẫn sử dụng thư viện Input Simulator để làm việc với Keyboard, Mouse Virtual
- [DEVEXPRESS] Hướng dẫn tích Filter Contain khi click chuột phải vào cell selection trên Gridview
- [C#] Tra cứu mã số thuế cá nhân bằng CMND hoặc CCCD
- [C#] Convert hình ảnh image thành Blurhash sử dụng trong loading image winform
- [POWERSHELL] Script sao lưu backup và nén database sqlserver
- [C#] Giới thiệu thư viện Autofac Dependency Injection
- [C#] Hướng dẫn tạo Windows Services đơn giản Winform
- [C#] Một click chuột điều khiển máy tính từ xa sử dụng Ultraviewer
- Hướng dẫn đóng gói phần mềm sử dụng Powershell biên dịch script thành file exe
- [C#] Hướng dẫn sử dụng Task Dialog trên NET 5
- [C#] Hướng dẫn xem lịch sử các trang web đã truy cập trên Chrome Browser
- [C#] Hướng dẫn lấy thông tin Your ID và Password của Ultraviewer 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!