如何写个死循环,既不独占线程,又不阻塞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是否能响应事件
});
}
}
}
使用async、await异步之后,就更好写了,非常优雅:

private async void button2_Click(object sender, EventArgs e)
{
while (true) // 死循环,但不阻塞UI线程
{
if (!this.IsDisposed)
{
textBox1.AppendText("测试\r\n");
} await Task.Delay(500);
}
}
如何写个死循环,既不独占线程,又不阻塞UI线程?的更多相关文章
- 在什么情况下,不写notify()或者notifyAll()就能唤醒被wait()阻塞的线程?
之前再看java关于线程的某视频时,发现在JDK源码中,join()=join(0)=wait()=wait(0),但是视频中在join()了之后,并没有用notify()或者notifyAll()去 ...
- C#.NET使用Task,await,async,异步执行控件耗时事件(event),不阻塞UI线程和不跨线程执行UI更新,以及其他方式比较
使用Task,await,async,异步执行事件(event),不阻塞UI线程和不跨线程执行UI更新 使用Task,await,async 的异步模式 去执行事件(event) 解决不阻塞UI线程和 ...
- 千万别在UI线程上调用Control.Invoke和Control.BeginInvoke,因为这些是依然阻塞UI线程的,造成界面的假死
原文地址:https://www.cnblogs.com/wangchuang/archive/2013/02/20/2918858.html .c# Invoke和BeginInvoke 区别 Co ...
- Qt线程QThread简析(8个线程等级,在UI线程里可调用thread->wait()等待线程结束,exit()可直接退出线程,setStackSize设置线程堆栈,首次见到Qt::HANDLE,QThreadData和QThreadPrivate)
QThread实例代表一个线程,我们可以重新实现QThread::run(),要新建一个线程,我们应该先继承QThread并重新实现run()函数. 需要注意的是: 1.必须在创建QThread对象之 ...
- Qt中运行后台线程不阻塞UI线程的方案
有一个想法,一个客户端,有GUI界面的同时也要向网络服务器发送本地采集的数据,通过网络发送数据的接口是同步阻塞的,需要等待服务器响应数据. 如果不采用后台线程的方案,用主UI线程关联一个定时器QTim ...
- jquery中的ajax请求,阻塞ui线程的解决方案(自己总结的demo)
/*****************************************************/ function getAjaxData(url,data){ showLoading( ...
- android的AsyncTask.get()方法会阻塞UI线程
AsyncTask.get()方法, 是有阻塞UI的能力的.
- Flutter 避免阻塞ui线程
import 'dart:async'; import 'dart:isolate'; import 'package:flutter/material.dart'; import 'package: ...
- C# 多线程详解 Part.02(UI 线程和子线程的互动、ProgressBar 的异步调用)
我们先来看一段运行时会抛出 InvalidOperationException 异常的代码段: private void btnThreadA_Click(object sender, ...
- jQuery同步Ajax带来的UI线程阻塞问题及解决办法
俗话说不作死就不会死,今天作死了一回,写了一个比较二逼的函数,遇到了同步Ajax引起的UI线程阻塞问题,在此记录一下. 事情起因是这样的,因为页面上有多个相似的异步请求动作,本着提高代码可重用性的原则 ...
随机推荐
- 增长实验室-ab分流的流量保护功能介绍
介绍ab分流的流量保护功能之前,先普及一下ab分流的一些概念和术语 名词解释: 实验:用来验证某个决定请求处理方式的功能或策略的一部分流量,通常用来验证某个功能或策略对系统指标(如PV/UV,CRT, ...
- tortoiseGit教程(常用图文教程)
需求: gitTorise是git的比较好用的一个图形化工具,本文目的在于对tortoiseGit常见使用进行一个总结. 对于git常见的使用有: 1. 建立仓库 2. 提交代码 3. 更新代码 4. ...
- 聊聊分布式 SQL 数据库Doris(八)
稀疏索引 密集索引:文件中的每个搜索码值都对应一个索引值,就是叶子节点保存了整行. 稀疏索引:文件只为索引码的某些值建立索引项. 稀疏索引的创建过程包括将集合中的元素分段,并给每个分段中的最小元素创建 ...
- C# 面试常见递归算法
前言 今天我们主要总结一下C#面试中常见递归算法. C#递归算法计算阶乘的方法 一个正整数的阶乘(factorial)是所有小于及等于该数的正整数的积,并且0的阶乘为1.自然数n的阶乘写作n!.180 ...
- 什么是物理信息系统(cps)?
物理信息系统(Cyber-Physical Systems,简称CPS)是由计算机.网络和物理组件相互交互的智能系统.它集成了实时计算.通信网络和物理过程控制,以提供智能化的感知.决策和执行功能. C ...
- 数据库系列:MySQL不同操作分别用什么锁?
数据库系列:MySQL慢查询分析和性能优化 数据库系列:MySQL索引优化总结(综合版) 数据库系列:高并发下的数据字段变更 数据库系列:覆盖索引和规避回表 数据库系列:数据库高可用及无损扩容 数据库 ...
- Android Studio 学习-第三章 Activity 第一组
事先申明:所有android 类型的学习记录全部基于<第一行代码 Android>第三版,在此感谢郭霖老师的书籍帮助. 1.手动创建Activity 在Project类型目录中寻找到 项目 ...
- TCP连接断开:为什么要挥手四次
本文分享自华为云社区<解密TCP连接断开:四次挥手的奥秘和数据传输的安全>,作者: 努力的小雨 . TCP 连接断开 在当今数字化时代,互联网已经成为了人们生活中不可或缺的一部分.而在互联 ...
- GHOST 系统安装教程 轻松一键,系统恢复到最佳状态
硬盘安装系统 安装前准备 1.保证能够正常进入系统: 2.下载Ghost系统镜像文件: 3.下载镜像安装器: 安装步骤 1.下载Ghost系统镜像"Win7_x64_Pure_5.07.GH ...
- 【笔记】负载均衡Robbin之不同服务使用不同的策略
裂开裂开,搞这么久忘记导入依赖 妈卖批 又不报错 还能让我玩 我以为全部导入了. 话不多说,开始演示. 介绍 给不同的服务 配置 不同的 负载均衡策略 这里使用 用户模块 进行访问其它两个模块的con ...