多线程并行执行任务并控制并行数量

 一、实现代码(对共享资源修改时需要添加锁,以下测试未对共享数据修改,只是并行读取数据,不需要加锁处理。)

方法一:使用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);

//其它逻辑。。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值