『QQ:1353814576』

C#线程池 线程数量达到设置的最大并发数量后 任务异常终止问题


C#线程池 线程数量达到设置的最大并发数量后 任务异常终止问题 以及替代方案

多线程有一些优点使得它开发应用很广泛,很多公司招聘开发就直接标注了多线程开发经验要求。

一些优点:

(1)使的程序的响应速度加快,避免阻塞用户界面 提升程序体验;

(2)处理大批量任务时 使用多线程可以提高CPU利用率 同理资源利用率更好;

(3)多线程可以分别设置优先级以优化性能,程序响应更快

(4)在某些情况下程序设计开发相对更简单一些

适用场景

以下是最适合采用多线程处理:

(1)耗时或大量占用处理器的任务阻塞用户界面操作;

(2)各个任务必须等待外部资源 (如远程下载上传文件或 等待Internet连接)。


问题描述:

就拿我目前在实施的一个项目来说 大概需求是这样的:

在客户那边安装一台服务器 然后从对方共享的目录里面监听文件创建然后批量拉取到服务器上,然后再批量上传到另外一台服务器上,最开始使用采用了单线程单文件的方式 期间发现此共享目录文件量新增速度有点超出预估 实测基本每10s左右就有上千个文件诞生 0.0 然后在这种并发下程序直接爆炸。。。想着控制多线程并发量 就改成使用线程池(ThreadPool)来管理并发线程 本地用着也挺好的 但是发到现场就出问题了,刚开始跑感觉还行 就是当可用工作线程归零时 整个程序就好像睡着了等了很长时间也没见线程释放 虽然最后采取了我自己的写的线程管理

我的解决办法

  1. 创建一个 System.Threading.ManualResetEvent 用于控制线程创建
  2. 创建一个线程队列 用于管理线程控制数量
  3. 业务线程创建线前 执行ManualResetEvent.WaitOne(); 等待结束后就创建新的任务线程
  4. 创建一个定时循环线程 检查线程队列数量 如果大于一定值 就将ManualResetEvent 设置为等待状态 如果小于就设置为等待结束

本着求知欲 在网上找到和我问题类似的内容 分享一下

ThreadPool有个缺陷,当线程放入Http下载任务时,会出现线程挂起后请求彻底崩溃 (和我上面情况挺类似的 同属于网络文件传输情况下)

当使用ThreadPool.SetMaxThreads(int, int)设置了最大数量,一旦同时放入高出数量的http下载任务时,所有任务就会崩溃 解决方案

  1. 不限制最大数量 ThreadPool.SetMaxThreads
  2. 手动限制最大并发数量,在源头控制一下,相信比较简单

方案三: 可以试下 TaskFactory.Start 感觉比ThreadPool 可控性强一些