一、实现代码(对共享资源修改时需要添加锁,以下测试未对共享数据修改,只是并行读取数据,不需要加锁处理。)
方法一:使用Parallel.ForEach方法实现
/// <summary>
/// 多线程处理数据(可设置线程数量)
/// </summary>
private static void GetMaxTasks()
{
//数据源
var jobs = Enumerable.Range(0, 20);
//设置同一时间线程最大数量
ParallelOptions po = new ParallelOptions
{
MaxDegreeOfParallelism = 3
};
//返回处理结果
ConcurrentQueue<string> resSources = new ConcurrentQueue<string>();
List<string> resSource = new List<string>();
Parallel.ForEach(jobs, po, (item) =>
{
resSource.Add(item.ToString());
Console.WriteLine("Task Id :{0} , 值:{1},线程数:{2},Time:{3}", Thread.CurrentThread.ManagedThreadId, item, GetCurrentTaskNum(), DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss fff"));
//Console.WriteLine("Task id :{0} 值:{2},Time:{1} second", Task.CurrentId, DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss fff"), jobNr);
Thread.Sleep(400);
resSources.Enqueue(item.ToString());
});
//输出多线程处理结果
Console.WriteLine("处理结果:" + string.Join(",", resSources.ToList()));
}
/// <summary>
/// 获取当前运行的线程数量
/// </summary>
/// <returns></returns>
private static int GetCurrentTaskNum()
{
int MaxWorkerThreads, miot, AvailableWorkerThreads, aiot;
//获得最大的线程数量
ThreadPool.GetMaxThreads(out MaxWorkerThreads, out miot);
AvailableWorkerThreads = aiot = 0;
//获得可用的线程数量
ThreadPool.GetAvailableThreads(out AvailableWorkerThreads, out aiot);
//返回线程池中活动的线程数
return MaxWorkerThreads - AvailableWorkerThreads;
}
方法二:通过分页生成Task实现
int pageNum =5;
int pageCount = orderList.Count() / pageNum + (orderList.Count() % pageNum == 0 ? 0 : 1);
int pageIndex = 0;
while (pageIndex < pageCount)
{
var curOrders = orderList.Skip(pageIndex * pageNum).Take(pageNum).ToList();
List<Task<bool>> tasks = new List<Task<bool>>();
for (int i = 0; i < curOrders.Count; i++)
{
if (string.IsNullOrWhiteSpace(curOrders[i]))
{
continue;
}
tasks.Add(Task<bool>.Run(() =>
{
//业务逻辑
return true;
}));
}
var task = Task.WhenAll<bool>(tasks);
task.Wait();
var resSource = task.Result; //返回task里的结果
pageIndex++;
}
二、效果图
三使用SemaphoreSlim
是一个轻量级的信号量,用于控制对共享资源的并发访问。你可以用它来限制同时运行的任务数量。
int maxConcurrentTasks = 10; // 最大并发任务数
var semaphore = new SemaphoreSlim(maxConcurrentTasks);
var tasks = new List<Task<int>>();
for (int i = 0; i < 100; i++) // 假设有100个任务需要执行
{
tasks.Add(Task.Run<int>(async () =>
{
await semaphore.WaitAsync(); // 等待信号量
try
{
// 执行任务
Console.WriteLine($"Task {i} is running");
// 模拟任务执行时间
await Task.Delay(1000);
return i;
}
finally
{
semaphore.Release(); // 释放信号量
}
}));
}
//等待所有任务执行完毕
await Task.WhenAll(tasks);
var syncCount = tasks.Sum(t => t.Result);
//其它逻辑。。。