parallel(parallel下载)快来看
参考文档:Parallel.ForEach 方法 | Microsoft Learn加州消费者隐私法案 禁用图标加州消费者隐私法案 禁用图
场景描述:在面对需要下载大量文件或同时执行大量任务的挑战时,多线程技术成为提高效率的关键工具这种方法就像优化了的生产线,各个部分同步协作,使整体工作更为流畅和迅速想象一下,你面临一个包含1,000个文件下载或者有多个可以并行处理的任务的时候。
在传统的单线程模型中,这将是一个漫长的等待过程但通过多线程,我们可以将这个大任务拆分成多个小任务并行执行,从而大大缩短完成时间,提高整体效率然而,仅仅完成任务是不够的为了确保用户和其他相关方实时了解进展情况,我们需要一个高效的进度跟踪和报告机制。
这可以通过建立实时监控系统或利用进度条、日志和通知来实现这样用户,都可以在任何时候了解项目的当前状态和预期进度下面就思考两种实现方式:多线程和并行库的用法主要是体会使用模型的使用多线程处理实现过程:示例代码:
using System; using System.Threading; using System.Threading.Tasks; classProgram { staticint currentFile =
0; staticobject lockObject = newobject(); staticvoidMain(string[] args) { constint
NUM_FILES = 1000; constint NUM_THREADS = 20; // 创建一个计数器,以便在所有线程完成后更新状态 CountdownEvent countdown = 。
new CountdownEvent(NUM_THREADS); // 创建20个下载线程for (int i = 0; i < NUM_THREADS; i++) {
int threadIndex = i; Task.Run(() => { // 模拟下载过程for (int j = threadIndex; j < NUM_FILES; j += NUM_THREADS) { DownloadFile(j); ReportProgress(NUM_FILES);
// 报告下载进度 } // 当前线程完成下载,向计数器发信号 countdown.Signal(); }); } 。
// 等待所有线程完成 countdown.Wait(); // 所有线程都已完成,将状态标记为已完成 Console.WriteLine("所有文件下载已完成!"。
); } staticvoidDownloadFile(int fileIndex) { // 模拟下载过程 Thread.Sleep(100);
// 假设每个文件需要10毫秒下载 Console.WriteLine($"文件 #{fileIndex} 已下载完毕!"); } staticvoidReportProgress
(int NUM_FILES) { lock(lockObject) { int current = Interlocked.Increment(
ref currentFile); Console.WriteLine($"当前进度:{current}/{NUM_FILES}"); } } }
1.定义常量:NUM_FILES表示总文件数量,这里设定为1000NUM_THREADS表示线程数量,这里设定为202.创建一个CountdownEvent对象countdown,用于在所有线程完成后更新状态。
3.创建20个下载线程:使用Task.Run()创建一个任务,并在每个任务中执行相应的操作每个线程根据索引threadIndex来决定从哪个文件开始下载,通过循环递增NUM_THREADS来实现线程间的文件分配。
在循环中调用DownloadFile()方法来模拟下载文件,并在下载完成后调用ReportProgress()方法报告下载进度当线程完成下载后,通过countdown.Signal()向计数器发信号4.使用countdown.Wait()等待所有线程完成。
5.所有线程都已完成,输出提示信息:“所有文件下载已完成!”6.DownloadFile()方法模拟文件下载过程:使用Thread.Sleep()方法来模拟下载耗时,这里假设每个文件需要100毫秒下载输出下载完毕的文件信息。
7.ReportProgress()方法用于报告下载进度:使用lock语句加锁,确保多个线程同时操作currentFile变量时不会产生竞争条件使用Interlocked.Increment()原子地递增currentFile变量,获取当前下载的文件数。
输出当前下载进度信息总体而言,该程序通过创建多个线程来并行下载文件,并使用计数器来跟踪所有线程的完成状态每个线程负责下载部分文件,并在完成后报告当前的下载进度最后,当所有线程都完成时,输出下载完成的提示信息。
使用并行库的处理过程:示例代码:using System; using System.Threading.Tasks; using System.Collections.Concurrent; class
Program { staticint currentFile = 0; staticobject lockObject = newobject(); staticvoidMain
(string[] args) { constint NUM_FILES = 1000; // 使用ParallelOptions来跟踪并行任务的进度var parallelOptions =
new ParallelOptions { MaxDegreeOfParallelism = 20// 设置最大并行度 }; // 使用Parallel.ForEach并行下载文件
Parallel.ForEach( Partitioner.Create(0, NUM_FILES), // 使用分区器创建任务范围 parallelOptions, (range, loopState) => {
for (int j = range.Item1; j < range.Item2; j++) { DownloadFile(j); ReportProgress(NUM_FILES);
// 报告下载进度 } }); // 所有任务完成后输出信息 Console.WriteLine("所有文件下载已完成!"
); } staticvoidDownloadFile(int fileIndex) { // 模拟下载过程 Task.Delay(100).Wait();
// 假设每个文件需要100毫秒下载 Console.WriteLine($"文件 #{fileIndex} 已下载完毕!"); } staticvoidReportProgress
(int NUM_FILES) { lock(lockObject) { int current = Interlocked.Increment(
ref currentFile); Console.WriteLine($"当前进度:{current}/{NUM_FILES}"); } } }
初始化并行任务:使用并行库,你可以利用Parallel.For或Parallel.ForEach来简化并行任务的创建和管理这些方法会自动处理任务的分发和管理,无需手动管理线程分发任务:Parallel.For或Parallel.ForEach会根据可用的处理器核心数或任务的工作量自动分发任务。
你只需指定任务的起始和结束范围报告进度:由于Parallel类提供了内置的机制来跟踪任务的进度,所以你可能需要使用ParallelOptions和ParallelLoopState来跟踪和报告任务的进度。
在这个版本中,我们使用Parallel.ForEach来并行处理文件的下载任务我们使用了Partitioner.Create来创建任务的范围,并使用ParallelOptions来控制并行度此外,进度报告也被稍微简化,因为Parallel类本身提供了一个更简洁的方法来处理这种情况。
参考文档:Parallel.ForEach 方法 (System.Threading.Tasks) | Microsoft Learn加州消费者隐私法案 (CCPA) 禁用图标加州消费者隐私法案 (CCPA) 禁用图标
C#并发实战Parallel.ForEach使用-CSDN博客关于c#:Parallel.ForEach(task.Wait)和Task.WaitAll之间的区别 | 码农家园#文章首发挑战赛##跨年幸运签#
#挑战30天在头条写日记##自律学习计划#
免责声明:本站所有信息均搜集自互联网,并不代表本站观点,本站不对其真实合法性负责。如有信息侵犯了您的权益,请告知,本站将立刻处理。联系QQ:1640731186