带任务完成通知功能的ThreadPool

.Net内置的ThreadPool类大大方便了多线程程序的开发,.Net程序员不用像Java程序员那样自己去写线程池或者找别人写好的线程池了。

不过ThreadPool也有用起来不方便的地方,因为ThreadPool是一个进程内的单一线程池,无法构建单一的线程池,由于所在的线程中可能有其他地方向ThreadPool中添加任务,因此ThreadPool没有提供一个“放进去的所有任务执行完毕”这样的功能。难道我们就没有办法了吗?

不用担心,其实非常简单,只要借助于学习《操作系统》中PV操作、信号量的知识点,可以很轻松的解决。为每个放到ThreadPool中的任务关联一个信号量,每个任务执行完毕后执行信号量的Set操作,Queue任务的主线程维护一个每个任务管理信号量的列表,把所有任务都Queue到ThreadPool中以后,逐个调用信号量的Wait操作,这样如果这个信号量对应的任务还没有执行完毕,那么Wait操作就会等待,如果执行完毕则Wait操作就不会阻塞,这样当所有的信号量Wait都返回了,就说明放进去的所有任务就都执行完成了。

我封装了一个简单的ThreadPoolEx类如下:

 

    public class ThreadPoolEx
    {
        private class WorkItemInfo
        {
            public AutoResetEvent AutoResetEvent { get; set; }
            public WaitCallback WaitCallback { get; set; }
            public object UserState { get; set; }
        }

        private List<AutoResetEvent> handlerStack = new List<AutoResetEvent>();
        public void QueueWorkItem(WaitCallback callBack,object userstate)
        {
            WorkItemInfo info = new WorkItemInfo();
            info.AutoResetEvent = new AutoResetEvent(false);
            handlerStack.Add(info.AutoResetEvent);
            info.WaitCallback = callBack;
            info.UserState = userstate;
            
            ThreadPool.QueueUserWorkItem((state) => {
                WorkItemInfo workItemInfo = (WorkItemInfo)state;
                try
                {
                    workItemInfo.WaitCallback(workItemInfo.UserState);
                }
                finally
                {
                    workItemInfo.AutoResetEvent.Set();
                }
            }, info);
        }

        public void WaitAllComplete()
        {
            foreach(AutoResetEvent handler in handlerStack)
            {
                handler.WaitOne();
            }
        }
    }

所有任务Queue进去以后,调用WaitAllComplete方法,当WaitAllComplete方法返回以后就说明任务执行完毕了。

调用方法实例代码如下:

ThreadPoolEx tpe = new ThreadPoolEx();
            for (int i = 100; i > 0; i--)
            {
                tpe.QueueWorkItem((state) =>
                {
                    Console.WriteLine(state);

                },i);               
            }
            tpe.WaitAllComplete();

Console.WriteLine('执行完成!');

 

如鹏网.Net培训班正在报名,有网络的地方就可以参加如鹏网的学习,学完就能高薪就业,点击此处了解

 

    三年前只要懂“三层架构”就可以说“精通分层架构”;现在则需要懂IOC(AutoFac等)、CodeFirst、lambda、DTO等才值钱;

    三年前只要会SQLServer就可以说自己“精通数据库开发”;现在则需还需要掌握MySQL等开源数据库才能说是“.Net开源”时代的程序员;

    三年前只要会进行用户上传内容的安全性处理即可;现在则需要熟悉云存储、CDN等才能在云计算时代游刃有余;

    三年前只要掌握Lucene.Net就会说自己“熟悉站内搜索引擎开发”;现在大家都用ElasticSearch了,你还用Lucene.Net就太老土了;

    三年前发邮件还是用SmtpClient;现在做大型网站发邮件必须用云邮件引擎;

    三年前缓存就是Context.Cache;现在则是Redis、Memcached的天下;

    如鹏网再次引领.Net社区技术潮流!点击此处了解如鹏网.Net最新课程

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值