-
如何写个死循环,既不独占线程,又不阻塞UI线程?
如果死循环独占线程,500个死循环要占用500个线程,如果死循环不独占线程,500个死循环,用200个线程也行,用20个线程也行,无非是执行的慢点
这样可以把同步操作改写为异步,并且节省线程占用
问个问题:写个Socket服务端,接收数据不准用BeginReceive和ReceiveAsync,只能用Receive,Socket客户端10000个,线程池最大不准超过1000,如何实现?
网上是用Select模型,要维护一个Socket对象列表,如果用下面的代码,可以不用维护Socket对象列表,直接有多少Socket对象,就写多少while(true)
代码:
using System; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; using Utils; /** * 如何写个死循环,既不独占线程,又不阻塞UI线程 */ namespace test { public partial class Form1 : Form { private int _n = 0; private bool _run1 = false; private bool _run2 = false; private TaskSchedulerEx _task1 = new TaskSchedulerEx(2, 2); //只给2个线程 public Form1() { InitializeComponent(); ThreadPool.SetMaxThreads(12, 12); //最多给12个线程 ThreadPool.SetMinThreads(10, 10); } private void Form1_Load(object sender, EventArgs e) { } /// <summary> /// 测试1 /// 现象:会输出i=5,也会输出i=15,button3有事件响应,因为20个死循环,2个线程也能处理,只不过处理速度慢,加大线程池容量可加快处理速度 /// </summary> private void button1_Click(object sender, EventArgs e) { _n = 0; button1.Enabled = false; button2.Enabled = true; _run1 = true; _run2 = false; textBox1.Text = string.Empty; for (int i = 1; i <= 20; i++) //启动20个死循环 { _task1.Run(async (obj) => //用_task1(只给2个线程)启动20个死循环 { dynamic var = (dynamic)obj; while (_run1) //此while不会独占线程 { Task t = Task.Factory.StartNew(() => { Thread.Sleep(100); Interlocked.Increment(ref _n); if (var.i == 5 || var.i == 15) { int a1; int a2; int m1; int m2; ThreadPool.GetMaxThreads(out m1, out a1); ThreadPool.GetAvailableThreads(out m2, out a2); Log("当前使用辅助线程数:" + (m1 - m2) + ",当前使用异步线程数:" + (a1 - a2) + ",i=" + var.i + ",n=" + _n); } }); await t; } }, new { i = i }); } } /// <summary> /// 测试2 /// 现象:只输出i=5,不输出i=15,button3不能响应事件,因为有20个死循环,12个线程不够用,但因为12个线程比较多,所以处理速度较快 /// </summary> private void button2_Click(object sender, EventArgs e) { _n = 0; button1.Enabled = true; button2.Enabled = false; _run1 = false; _run2 = true; textBox1.Text = string.Empty; for (int i = 1; i <= 20; i++) //启动20个死循环 { Task.Factory.StartNew((obj) => //用Task(最多12个线程)启动20个死循环 { dynamic var = (dynamic)obj; while (_run2) //此while会独占一个线程 { Thread.Sleep(100); Interlocked.Increment(ref _n); if (var.i == 5 || var.i == 15) { int a1; int a2; int m1; int m2; ThreadPool.GetMaxThreads(out m1, out a1); ThreadPool.GetAvailableThreads(out m2, out a2); Log("当前使用辅助线程数:" + (m1 - m2) + ",当前使用异步线程数:" + (a1 - a2) + ",i=" + var.i + ",n=" + _n); } } }, new { i = i }); } } private void button3_Click(object sender, EventArgs e) { Task.Factory.StartNew(() => { Log("button3_Click 有响应"); //测试button3是否能响应事件 }); } } }
栏目列表
最新更新
nodejs爬虫
Python正则表达式完全指南
爬取豆瓣Top250图书数据
shp 地图文件批量添加字段
爬虫小试牛刀(爬取学校通知公告)
【python基础】函数-初识函数
【python基础】函数-返回值
HTTP请求:requests模块基础使用必知必会
Python初学者友好丨详解参数传递类型
如何有效管理爬虫流量?
SQL SERVER中递归
2个场景实例讲解GaussDB(DWS)基表统计信息估
常用的 SQL Server 关键字及其含义
动手分析SQL Server中的事务中使用的锁
openGauss内核分析:SQL by pass & 经典执行
一招教你如何高效批量导入与更新数据
天天写SQL,这些神奇的特性你知道吗?
openGauss内核分析:执行计划生成
[IM002]Navicat ODBC驱动器管理器 未发现数据
初入Sql Server 之 存储过程的简单使用
这是目前我见过最好的跨域解决方案!
减少回流与重绘
减少回流与重绘
如何使用KrpanoToolJS在浏览器切图
performance.now() 与 Date.now() 对比
一款纯 JS 实现的轻量化图片编辑器
关于开发 VS Code 插件遇到的 workbench.scm.
前端设计模式——观察者模式
前端设计模式——中介者模式
创建型-原型模式