惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

IT之家
IT之家
博客园_首页
S
SegmentFault 最新的问题
罗磊的独立博客
博客园 - 【当耐特】
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
阮一峰的网络日志
阮一峰的网络日志
D
Docker
雷峰网
雷峰网
Google DeepMind News
Google DeepMind News
博客园 - 司徒正美
V
V2EX
大猫的无限游戏
大猫的无限游戏
V
Visual Studio Blog
腾讯CDC
宝玉的分享
宝玉的分享
酷 壳 – CoolShell
酷 壳 – CoolShell
人人都是产品经理
人人都是产品经理
T
Tailwind CSS Blog
Vercel News
Vercel News
H
Help Net Security
博客园 - Franky
D
DataBreaches.Net
aimingoo的专栏
aimingoo的专栏

博客园 - 寒带鱼

协程的原理(Coroutine Theory) SQLite数据库学习小结——Frameworks层实现 SQLite数据库学习小结——native层实现 如何用javascript取出session中的值? - 寒带鱼 - 博客园 连接池泄露了~ Session丢失的解决办法小结 返回动态生成的数组的方法 [翻译]编写高性能Web应用程序的10个技巧 [译]30分钟正则表达式指导 操作Word文档的类(VB.NET) MySQL5.0中文手册(13.1. 数据定义声明) ADO.NET对象模型 妹妹生了个女儿,纪念一下 从ASP.NET得到Microsoft Word文档 短期目标 做项目的一点收获之二 2005年中国软件产业最大规模前100家企业名单 关于文件操作的问题 数组定义的疑问
做项目的一点收获之一
寒带鱼 · 2005-10-24 · via 博客园 - 寒带鱼

前言

        八月初接了个活,经过两个多月(中间有一个星期的时间去了趟郑州,还有段时间忙老师的项目报告)的学习和开发,现在终于接近尾声了。项目规模不大,但杂七杂八的要用到很多东西,其中有不少都是第一次接触到,着实让我头大了几回,在这里记下一点收获,以做日后参考之用(我得记性太差:-()。

使用线程

        项目要求对内网和外网数据库进行同步,每个服务器都有若干数据库,每个数据库又包含若干数据表。一个办法是对每个要同步的数据表在其中一个服务器上进行查询,有更新就下载到本地,然后再上传到另一个服务器对应的数据表中,然后再对下一个数据表进行同样的操作,可想而知,这是多笨的办法。于是决定采用多线程,我写了一个数据表操作类,类中包含了每个线程需要的信息(包括连接信息、计数器、各种标志位等,当然得有下载和更新数据的方法),在主程序中对每个数据表生成一个该类的实例,每个实例对应四个线程(分别对应内网上传、下载和外网上传、下载),然后在到达更新周期时启动线程来完成同步操作。关于多线程的更多资料见[ZT]C#的多线程机制探索(1)。


        但是,这样又带来了另一个问题:如果数据表很多,则同时启动的线程也会很多,创建太多的线程可能会导致系统由于过度消耗内存而用完内存或“切换过度”。例如如果有100个表,那么最多同时启动的线程将达到400个,很难想象这时会是什么样的情况。


        最后的解决办法是采用线程池。线程池为线程生命周期开销问题和资源不足问题提供了解决方案。通过对多个任务重用线程,线程创建的开销被分摊到了多个任务上。其好处是,因为在请求到达时线程已经存在,所以无意中也消除了线程创建所带来的延迟。这样,就可以立即为请求服务,使应用程序响应更快。默认情况下,每个进程可以产生25个线程池线程。然而,这个数量可以通过编辑mscoree.h文件中的CorSetMaxThreads成员加以改变。如果有额外的线程请求,这个请求将加入到队列中,直到某个线程完成了分配给它的任务,返回到线程池中为止,从而可以防止资源不足。


        使用线程池有几种方法,我使用的是QueueUserWorkItem方法,该方法的使用方法如下:

Public static bool QueueUserWorkItem(WaitCallback callBackk,object state);


        callBack表示线程池中的线程执行任务时要调用的委托,state表示包含状态的对象,该对象将在线程执行任务时传递给委托。返回true表示方法调用成功。


        因为是静态方法,所以在调用时不需要先声明线程池的实例。例如:
        

ThreadPool.QueueUserWorkItem(new WaitCallBack(someMethod),someObject);


        ThreadPool类中还有很多其他方法,目前还没用过,就不记了。


        在使用线程时产生了一个疑问:使用线程池时传递给委托的方法要带一个object类型的参数,而在使用线程时传递给委托的方法不能带任何参数,线程池和线程的这点不同可以带来什么好处呢?以后要弄明白。

        今天先扯这么多。