如果死循环独占线程,500个死循环要占用500个线程,如果死循环不独占线程,500个死循环,用200个线程也行,用20个线程也行,无非是执行的慢点
这样可以把同步操作改写为异步,并且节省线程占用
问个问题:写个Socket服务端,接收数据不准用BeginReceive和ReceiveAsync,只能用Receive,Socket客户端10000个,线程池最大不准超过1000,如何实现?
网上是用Select模型,要维护一个Socket对象列表,如果用下面的代码,可以不用维护Socket对象列表,直接有多少Socket对象,就写多少while(true)
代码:
using System; System.Text; System.Threading; System.Threading.Tasks; System.Windows.Forms; Utils; /** * 如何写个死循环,既不独占线程,又不阻塞UI线程 */ namespace test { public partial class Form1 : Form { private int _n = 0; bool _run1 = falsebool _run2 = private TaskSchedulerEx _task1 = new TaskSchedulerEx(2,2); //只给2个线程 public Form1() { InitializeComponent(); ThreadPool.SetMaxThreads(12,1)">12); 最多给12个线程 ThreadPool.SetMinThreads(10,1)">10); } void Form1_Load(object sender,EventArgs e) { } /// <summary> /// 测试1 现象:会输出i=5,也会输出i=15,button3有事件响应,因为20个死循环,2个线程也能处理,只不过处理速度慢,加大线程池容量可加快处理速度 </summary> void button1_Click(; button1.Enabled = ; button2.Enabled = true; _run1 = ; _run2 = ; 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 || 15) { int a1; int a2; int m1; int m2; ThreadPool.GetMaxThreads(out m1,out a1); ThreadPool.GetAvailableThreads(out m2,1)"> a2); Log("当前使用辅助线程数:" + (m1 - m2) + ,当前使用异步线程数:" + (a1 - a2) + ,i=" + var.i + ,n=" + _n); } }); await t; } },new { i = i }); } } 测试2 现象:只输出i=5,不输出i=15,button3不能响应事件,因为有20个死循环,12个线程不够用,但因为12个线程比较多,所以处理速度较快 void button2_Click( { Task.Factory.StartNew((obj) => 用Task(最多12个线程)启动20个死循环 while (_run2) 此while会独占一个线程 { Thread.Sleep(); Interlocked.Increment( _n); ) { m2; ThreadPool.GetMaxThreads( a1); ThreadPool.GetAvailableThreads( a2); Log( _n); } } },1)"> i }); } } void button3_Click( { Log(button3_Click 有响应"); 测试button3是否能响应事件 }); } } }
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。