我们是五月的花海 , 用青春拥抱时代|

兴想事成

园龄:12年10个月粉丝:25关注:97

多线程之线程池任务管理通用模板

     已经一年多的时间没有使用多线程了.最近需要做一个异步发邮件的功能,为了给同事写一个例子,想起以前写的爬虫的时候,

 一个带我的人给了我一个通用的模板类, 我觉得那个例子很好,于是我根据自己的理解,写出了如下的代码.

模型描述

首先是一个通用的 计数器.包括 当前在运行的线程数Current,执行成功的数量Success,执行失败的数量Error,以及总完成数量Finish.

为了方便大家理解,我还是做一下简要的说明.大致过程是这样的: 首先有一批任务进来,需要把这些任务用多线程来处理.(我这里使用的是线程池.)

关于池的概念大家应该埠陌生.比如 数据库的连接池.

   任务一个一个的分配,每个任务都是开启一个子线程单独执行的,一边分配任务,一边执行任务.在不停的分配任务的时候,会出现这样一种情况,

就是任务已经分配出去很多了,但是执行的不够快,这个时候需要主线程等待一下,过一会再分配新的任务.

   我将上面的描述用一个日常生活中的例子来做说明: 一个小饭店只有10个座位,10点开始营业,到了12点吃饭的时间,外面来了100个客人,

挨个挨个的进入饭店就餐.

   第一个人进,占位置1个,第二个人进入, 占位置1个, 第三个人进入,占位置1个,

   第四个人进入占位置1个,第五个人进入占位置1个,  然后第一个人打包的走了,有个位置空出来了,

   现在已经使用了 4个位置,至于进来以后坐什么地方,这个不用管.

   第六个人进入占了位置1个,...第九个人进来了,占位置1个,第2个人吃完了,第十个人进来了,第是一个人进来了,第十二个人进来了,

   第三个人吃完了,第十三个人进来了,

   第十四个人想进来,抱歉,已经坐满了,要等待,过1分钟再看有没有位置,如果没有人离开,外面的人一直不能进来,

   过了五分钟, 再看发现一个桌子四个人都离开了,于是第十四个人进来了,第十五个人进来了....后面的类似前面的...

   废话啰嗦完了,上代码

先上一个计数器读写的类

 

复制代码
  public sealed class ThreadCounter
    {
        private int current = 0;
        private int error = 0;
        private int success = 0;
        private int finish = 0;

        private static object writeObj = new object();

        public int getCurrent()
        {
            lock (writeObj) return current;
        }

        public int getError()
        {
            lock (writeObj) return error;
        }

        public int getSuccess()
        {
            lock (writeObj) return success;
        }

        public int getFinish()
        {
            lock (writeObj) return finish;
        }

        public void setAddCurrent()
        {
            lock (writeObj) current++;
        }

        public void setSuccess()
        {
            lock (writeObj)
            {
                success++;
                current--;
            }
        }

        public void setError()
        {
            lock (writeObj)
            {
                error++;
                current--;
            }
        }

        public void setFinish()
        {
            lock (writeObj) finish++;
        }
    }
复制代码

 

主体运行业务处理类

新建类 RunManager,定义一个私有字段,一个随机数生成类,一个线程计数类

1   public class RunManager
2     {
3         private static int MaxThreadCount = 10;
4 
5         ThreadCounter tc = new ThreadCounter();
6 
7         Random random = new Random();
8     }

 

新增模拟任务的初始化方法

复制代码
/// <summary>
/// 最大开启的线程数
/// </summary>
 /// <param name="threadCount"></param>
public void RunStart(int threadMaxCount)
{
     //最大开启的线程数
     Console.WriteLine("设置最大线程数:" + threadMaxCount);

      MaxThreadCount = threadMaxCount;

      RunTask(100);
}
复制代码

 

线程池分配任务

复制代码
 1 public void RunTask(int taskCount)
 2 {
 3     string mss = "";
 4     string[] arr = new string[] {"|","/","-","\\" };
 5     int j = 0;
 6     while (true)
 7     {
 8         if (++j==4)
 9             j = 0;
10         Console.Clear();
11         Console.SetCursorPosition(1, 0);
12         Console.WriteLine("当前运行情况");
13         Console.Write("["+arr[j]+"]\t");
14             mss = string.Format("Query:{0} , Current:{1} , Success:{2} , Error:{3} , Finish:{4}", 
15                 taskCount, tc.getCurrent(),tc.getSuccess(), tc.getError(), tc.getFinish());
16         Console.WriteLine(mss);
17         Thread.Sleep(500);
18 
19         if (taskCount>0&&tc.getCurrent() < MaxThreadCount)
20         {
21             taskCount--;
22             tc.setAddCurrent();
23             ThreadPool.UnsafeQueueUserWorkItem(RuanCallBack, 0);
24         }
25         else if (taskCount==0)
26             taskCount = random.Next(60, 125);
27         else if (tc.getCurrent() >= MaxThreadCount)
28             Thread.Sleep(6000);
29     }
30}
复制代码

 

模拟线程运行所消耗的时间

复制代码
 1 public void RuanCallBack(object parms)
 2 {
 3     // 将传过来的参数, 整理为要查询的数据, 以及处理数据,写入文件,打包zip,
 4     // 发送邮件通知用户下载
 5     try
 6     {
 7         int t = random.Next(3, 7);
 8         Thread.Sleep(t * 1000);
 9         tc.setSuccess();
10     }
11     catch (Exception)
12     {
13         tc.setError();
14     }
15     finally
16     {
17         tc.setFinish();
18     }
19     //Console.WriteLine("当前线程序号:" + parms.ToString() + "\t线程停顿时间:" + t);
20 }
复制代码

 

调用

static void Main(string[] args)
 {
     RunManager r = new RunManager();
     r.RunStart(20);
     Console.Read();
     Console.WriteLine("运行结束");
 }

看看运行效果

 Nice!

原代码下载: 下载

posted @   兴想事成  阅读(1152)  评论(2编辑  收藏  举报
编辑推荐:
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起
  1. 1 Good-bye My Loneliness ZARD
  2. 2 Say OK Vanessa Hudgens
  3. 3 All The Love In The World The Corrs
  4. 4 Adesso E Fortuna ~炎と永遠~ 加藤いづみ
Say OK - Vanessa Hudgens
00:00 / 00:00
An audio error has occurred, player will skip forward in 2 seconds.

作词 : BIRGISSON, ARNTHOR/KOTECHA, SAVAN

作曲 : Savan Kotecha/Arnthor Birgisson

Vanessa Hudgens - Say OK

Album: V

You are fine

You are fine

You are fine

You are fine

You are sweet

But I'm still a bit naive with my heart

When you're close I don't breathe

I can't find the words to speak

I feel sparks

But I don't wanna be into you

If you are not looking for true love, oh oh

No I don't wanna start seeing you

If I can't be your only one

So tell me when it's not alright

When it's not ok

Will you try to make me feel better?

Will you say alright? (say alright)

Will you say ok? (Say ok)

Will you stick with me through whatever?

Or run away

(Say that it's gonna be alright)

(That it's gonna be ok)

Say OK

When you call I don't know

If I should pick up the phone every time

I'm not like all my friends

Who keep calling up the boys, I'm so shy

But I don't wanna be into you

If you don't treat me the right way

See I can only start seeing you

If you can make my heart feel safe (feel safe)

When it's not alright

When it's not ok

Will you try to make me feel better?

Will you say alright? (say alright)

Will you say ok? (Say ok)

Will you stick with me through whatever?

Or run away

(Say that it's gonna be alright)

(That it's gonna be ok)

(Don't run away, don't run away)

Let me know if it's gonna be you

Boy, you've got some things to prove

Let me know that you'll keep me safe

I don't want you to run away so

Let me know that you'll call on time

Let me know that you won't be shy

Will you wipe my tears away

Will you hold me closer

When it's not alright

When it's not ok

Will you try to make me feel better

Will you say alright? (say alright)

Will you say ok? (Say ok)

Will you stick with me through whatever?

Or run away

(Say that it's gonna be alright)

(That it's gonna be ok)

Say OK

(Don't run away, don't run away)

(Say that it's gonna be alright)

(That it's gonna be ok)

(Don't run away)

Will you say OK

(Say that it's gonna be alright)

(That it's gonna be ok)

(Don't run away)

You are fine

You are fine