LiaoLiao.WebAPI项目存在的问题-扩展技术选型

1.实际问题

使用Newlife框架(Newlife.core还有Xcode)出现了内存泄露问题(表现是iis线程内存不停增长,请求进不来)

image

 在架构上就是天然冲突。

IIS 是为

  • 网站

  • 管理后台

  • 企业系统

  • 表单提交

  • REST API

设计的。

它的核心假设是:

请求进来 → 快速处理 → 马上结束

IIS 的真实内部模型(简化)

image

关键点

  • 队列是有限的

  • 线程池是有限的

  • 请求必须“尽快结束”

小游戏服务端

  • 心跳 1s / 2s

  • 拉状态

  • 同步在线人数

  • 房间数据

  • 排行榜

  • 推送

  • 长轮询 / 半长连接

实际上在做的是:

伪长连接游戏服

比如:

 
10000 玩家 × 每秒 1 次心跳 = 10000 QPS

 每个请求里你还在做逻辑、查库、状态同步。

在这时会发生

IIS 并不会告诉你“我扛不住了”

它的表现是:

  • 请求排队

  • 超时

  • 新连接进不来

  • 浏览器卡住

  • 客户端请求无响应

你看到的现象就是:

“IIS 请求进不来”

但其实是

🔥 IIS 的请求队列满了


导致会“觉得是连接瓶颈”

因为看到的是:

  • CPU 还没满

  • 内存还没爆

  • 但请求卡死

这正是 IIS 的典型特征。

它不是“慢”,而是:

拒绝接新请求

newlife框架+IIS怎么调都不稳:

 

  • 调线程池 → 好一会

  • 调 maxConcurrentRequestsPerCPU → 好一会

  • 调队列长度 → 好一会

  • 但一上量又崩

 

因为在对抗 IIS 的设计初衷

 

NewLife 在“真正的游戏服场景”反而很强

如果把:

  • IIS

  • ASP.NET

  • HTTP

全部拿掉

只保留:

  • NewLife.Net

  • SocketServer

  • 自定义协议

那么:

NewLife 是非常强的

 

2.问题点

泄露点 ①:所有 XCode 实体默认开启 EntityCache

所有继承:

Entity<T>

的实体类,例如:

  • Room

  • User

  • Liao

  • ChatLog

  • OnlineUser

  • 等等


❌ 问题代码(默认行为)

 
Room.FindById(id); User.Find("xxx");

背后发生的是:

 
EntityCache.Entities[id] = entity;

永远不会删除。


 泄露等级

⭐⭐⭐⭐⭐(最高)

这是进程内存持续上涨的第一来源

 泄露点 ②:TimerX / Delay / Periodic 未集中托管

项目中存在大量:

 
TimerX.Delay(...) TimerX.Periodic(...)

❌ 问题本质

TimerX 内部是:

 
static Scheduler └── List<TimerX> └── Action 回调 └── 捕获 this

只要没 Dispose:

❌ GC 永远回收不了


泄露等级

⭐⭐⭐⭐⭐

这是第二大稳定增长来源


⚠️ 特别危险的写法

 
TimerX.Delay(() => { this.DoWork(); }, 1000);

👉 lambda 捕获整个 Service / Controller。


✅ 必须整改

禁止在任意地方直接用 TimerX。

统一:

BackgroundTaskManager.Add( new TimerX(OnTimer, null, 1000, 1000) );

并在程序关闭时:

Dispose();

或直接迁移到:

BackgroundService

(推荐)

 泄露点 ③:Controller / Service 中启动后台线程

 
Task.Run(() => { while(true) { ... Thread.Sleep(1000); } });

❌ 问题

  • 请求结束

  • HttpContext 被捕获

  • 用户信息被捕获

  • DI Scope 被捕获

  • 线程永远不结束


泄露等级

⭐⭐⭐⭐⭐(灾难级)

这是 IIS / Kestrel 下的大忌


✅ 必须整改

❌ Controller 禁止 Task.Run
❌ 禁止 while(true)

✅ 改为:

public class Worker : BackgroundService
{
    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        while (!stoppingToken.IsCancellationRequested)
        {
            ...
            await Task.Delay(1000);
        }
    }
}

 泄露点 ④:Static Service / Manager 类

例如:

 
public static class RoomManager { public static Dictionary<int, Room> Rooms = new(); }

❌ 问题

  • static 永生

  • Dictionary 无限增长

  • 没有过期策略


泄露等级

⭐⭐⭐⭐


✅ 建议

  • static 改为 DI 单例

  • 使用 MemoryCache + 过期

  • 明确最大容量

 泄露点 ⑤:事件订阅未解除

SomeService.OnMessage += Handler;

但没有:

-= Handler;

❌ 本质

事件 = 强引用链:

static publisher → subscriber

 泄露等级

⭐⭐⭐⭐

非常隐蔽,dump 才能查出来。


✅ 整改

  • 禁止 Controller 订阅事件

  • 所有事件必须可反注册

  • 或使用 WeakEvent


 泄露点 ⑥:XCode DAL / DbSession 未释放

var dal = DAL.Create(); dal.Query(sql);

❌ 问题

  • DbSession 持有连接

  • Session 被缓存

  • 连接池异常增长


 泄露等级

⭐⭐⭐


✅ 正确方式

using var dal = DAL.Create();

或统一走 Entity API。


 泄露点 ⑦:日志对象捕获大对象

你有:

Log.Info(JsonConvert.SerializeObject(obj));

obj 里包含:

  • 大 List

  • 用户集合

  • 房间状态


❌ 问题

  • Logger 内部异步队列

  • 消息未刷盘前一直在内存

  • 高并发下堆积


 泄露等级

⭐⭐⭐


✅ 建议

  • 日志不要打完整对象

  • 大对象只打 ID / Count


✅ 总体风险等级评估

模块风险
XCode 实体缓存 🔥🔥🔥🔥🔥
TimerX 🔥🔥🔥🔥🔥
后台线程 🔥🔥🔥🔥🔥
Static Manager 🔥🔥🔥🔥
事件 🔥🔥🔥🔥
DAL 🔥🔥🔥
日志

🔥🔥

结论:上述给出的问题都是框架本身代码的问题,而不是应用层代码的问题。

NewLife(Core + XCode)并不是“不能写 WebAPI”
而是:它是“服务端常驻进程框架”,不是“请求驱动框架”。

NewLife 的设计年代背景是:

  • .NET Framework

  • Windows Service

  • 游戏服

  • Socket Server

  • IM Server

  • 单体部署

  • 一台机器跑几年

而不是:

  • ASP.NET Core

  • Kestrel

  • 云原生

  • 容器

  • 横向扩展

  • 无状态 API

  • 高频伸缩


 所以现在的“问题”,其实是范式冲突

维度NewLifeWebAPI
生命周期 进程级 请求级
对象 长期存活 短生命周期
缓存 默认开启 明确声明
定时器 全局 HostedService
状态 常驻内存 无状态
static 合理 危险

Newlife不适合做webapi框架,搭配iis;只适合做基础框架,应用日志模块等。

3.同样是高并发,游戏服和WebApi的不同?

“高并发”不是一个维度。

真正决定架构是否合适的,从来不是 QPS,
而是👇

连接模型 + 生命周期模型 + 状态归属模型

游戏服是“状态驱动并发”
WebAPI 是“请求驱动并发”

它们看起来都“并发高”,
但底层运行模型完全不是一回事


一、游戏服的并发是什么并发?

游戏服的并发是:

大量长连接,同时在线

特点:

  • 一个连接 = 一个玩家

  • 连接持续几小时

  • 状态长期存在内存

  • 心跳维持

  • 数据频繁复用

模型是:

image

 这是“对象常驻模型”

Player
{
    UserId
    Socket
    Room
    Position
    HP
    Buffs
}

这个对象:

  • 创建一次

  • 用几小时

  • 最后断线销毁


所以游戏服的核心优化目标是:

目标原因
少 GC GC 会卡顿
多缓存 减少 IO
多 static
内存换 CPU 合理

 这正是 NewLife 的设计哲学。

所以在游戏服里:

  • static 是优点

  • Cache 是刚需

  • TimerX 非常自然

  • 全局对象完全合理


 二、WebAPI 的并发是什么并发?

WebAPI 的并发是:

大量短请求瞬间涌入

特点:

  • 一个请求 5–50ms

  • 请求结束立刻销毁

  • 无状态

  • 横向扩容

  • 随时重启

模型是:

image

这是“瞬时对象模型”

对象的理想寿命是:

毫秒级


 这两种模型的根本冲突

维度游戏服WebAPI
对象 常驻 瞬态
内存 世界状态 临时计算
生命周期 小时 毫秒
GC 尽量少 频繁可控
static 合理 危险
Cache 默认 明确

所以同样是 10 万并发:

  • 游戏服:10 万 连接

  • WebAPI:10 万 瞬时请求

这是完全不同的东西。


 三、为什么Newlife框架适合管理后台?

管理后台本质是什么?

低并发 + 高复用 + 高读取

特点:

  • 用户少(几十 / 几百)

  • 数据结构固定

  • 查询重复率高

  • 操作节奏慢

  • 不追求极限延迟

典型场景:

  • 用户列表

  • 配置表

  • 权限表

  • 字典表

  • 菜单表

这些数据:

  • 非常适合缓存

  • 非常适合 static

  • 几乎不增长

  • 变更极少

这正是 XCode EntityCache 的“完美场景”。


对比一下三个场景

场景是否适合 NewLife
游戏服 ✅ 非常合适
管理后台 ✅ 合适
WebAPI ❌ 默认不适合

不是并发问题。

生命周期模型问题


四、为什么“游戏服高并发”不会内存涨?

因为游戏服的内存模型是:

 
在线人数 = 内存上限
  • 10 万玩家

  • 就 10 万 Player 对象

  • 玩家下线 → 对象释放

这是:

有上限的并发

而 WebAPI 是:

  • 用户 ID 无限

  • 查询参数无限

  • URL 无限

  • 数据组合无限

你今天查:

 
/room?id=1001

明天查:

 
/room?id=1002

后天查:

 
/room?id=999999

 EntityCache 会把它们全记住。

于是:

 没有自然上限

这才是内存灾难。


所以会看到这个现象

系统内存走势
游戏服 稳定平台
管理后台 小平台
WebAPI 持续上涨

不是 GC 不行。

对象从来没被允许死亡


这就是一句最重要的话

游戏服并发是“状态并发”
WebAPI 并发是“请求并发”

这两者之间,没有任何“并发数”可以类比。

不同应用场景 → 生命周期模型不同 → 不能用同一套通用框架

后端系统的本质不是语言,也不是框架,而是:生命周期模型。


 五、后端常见三大场景,本质上是三种“生物形态”

这三类:

  • WebAPI

  • 管理后台

  • 小游戏服务器

表面都是服务端
本质是三种完全不同的“生命体”


(1)WebAPI ——「瞬时型系统」

生命周期模型

Request → Process → Response → Destroy

特征

  • 对象活几毫秒

  • 无状态

  • 可横向扩展

  • 可随时重启

  • 高 QPS

  • 弱一致性

适合的技术特征

项目需求
static
缓存 明确、有限
定时器 极少
内存状态
并发 请求并发

 这是 “函数式服务模型”

典型框架:

  • ASP.NET Core

  • Spring Boot

  • FastAPI

  • Gin


(2)管理后台 ——「长寿型系统」

生命周期模型

 
用户少 操作慢 数据稳定

特征

  • 并发低

  • 数据复用高

  • 查询重复

  • 强一致

  • 稳定优先

适合的技术特征

项目需求
static
EntityCache
单例
内存缓存
重启

👉 本质是:

“业务系统”

典型框架:

  • NewLife XCode

  • EF Core + Admin

  • Django Admin

  • 若依


(3)小游戏服务器 ——「常驻世界型系统」

生命周期模型

image

特征

  • 长连接

  • 内存即世界

  • 状态同步

  • 实时性

  • 延迟敏感

  • GC 敏感

适合的技术特征

项目需求
static
全局对象
内存状态
定时器
HTTP
IIS

 本质是:

“实时系统 / 状态机”


 三种模型根本无法统一

系统类比
WebAPI 函数
管理后台 应用程序
游戏服 操作系统

不能拿操作系统内核去写Web 接口

同理:

你也不可能用 WebAPI 框架去承载游戏世界。


六、为什么“通用框架”几乎都失败?

因为它们试图同时满足:

  • 短生命周期

  • 长生命周期

  • 状态型

  • 无状态型

这是物理上冲突的。

所以会看到:

  • 游戏框架不能优雅写 WebAPI

  • Web 框架写不好游戏服

  • 管理后台框架性能一塌糊涂


 所以真正成熟后端的思维是:

先选生命周期模型,再选框架。

而不是:

“我用 .NET / Java,应该选哪个框架?”

技术模型对照表

场景生命周期正确模型
REST API 毫秒 请求模型
管理后台 分钟~小时 应用模型
游戏服务器 小时~天 世界模型
IM 长连接 会话模型
网关 常驻 流量模型
任务调度 常驻 调度模型

 

 

“后端不是写接口,是管理生命周期。”

七、后端系统生命周期模型总图

后端系统的本质分类(不是按语言)

image

 

(1)瞬时系统(WebAPI / 微服务)

生命周期模型

 

image

特点关键词

  • 无状态

  • 横向扩展

  • 随时重启

  • 高 QPS

  • 对 GC 友好

  • 对 static 极度敏感

典型系统

  • WebAPI

  • 微服务

  • BFF

  • 接口网关(非连接型)

技术特征

项目是否
static
全局缓存
EntityCache
定时器 ⚠️ 极少
长连接
IIS
Kestrel

正确框架

  • ASP.NET Core

  • Spring Boot

  • FastAPI

  • Gin

函数模型


(2)应用系统(管理后台 / 业务系统)

生命周期模型

image

特点关键词

  • 并发低

  • 数据稳定

  • 查询复用高

  • 内存缓存非常有价值

  • 重启成本高

典型系统

  • 管理后台

  • ERP

  • CMS

  • 运维平台

  • 内部系统

技术特征

项目是否
static
EntityCache
单例
全局缓存
定时任务
长连接

正确框架

  • NewLife + XCode

  • Django Admin

  • 若依

  • ABP

应用模型


(3)常驻系统(游戏服 / IM / 实时系统)

生命周期模型

image

 

特点关键词

  • 长连接

  • 状态即内存

  • 世界常驻

  • 延迟敏感

  • GC 敏感

  • 极少重启

典型系统

  • 小游戏服务器

  • IM

  • 推送系统

  • 网关

  • 房间系统

  • 实时对战

技术特征

项目是否
static
全局状态
Timer
HTTP
IIS
Socket
WebSocket

正确框架

  • NewLife.Net

  • 自研 SocketServer

  • Netty

  • Skynet

  • Actor 模型

👉 世界模型


(4)三种模型的“绝对禁区”

这是最重要的一部分。


WebAPI 禁区

  • static Dictionary

  • EntityCache

  • TimerX

  • 后台线程

  • 常驻对象

  • 长连接状态

一句话:

请求结束,一切都应该消失。


游戏服禁区

  • IIS

  • Controller

  • HTTP 心跳

  • WebAPI 同步

  • 每次查数据库

一句话:

世界不能被请求打断。


管理后台禁区

  • 极致高并发

  • 每请求建世界

  • 重复计算

  • 禁缓存

一句话:

稳定优先于性能。


选型只要问 3 个问题

问题 1:

这个系统的“核心对象”要活多久?

  • 毫秒 → WebAPI

  • 分钟 / 小时 → 管理后台

  • 小时 / 天 → 游戏服


 问题 2:

状态主要存在在哪里?

  • 数据库 → WebAPI

  • 内存缓存 → 管理后台

  • 内存世界 → 游戏服


 问题 3:

系统能不能随时重启?

  • 能 → WebAPI

  • 勉强 → 管理后台

  • 不能 → 游戏服

八、“有登录 / 下线” ≠ “是常驻系统”

这是整个后端领域最容易混淆的点之一。


 关键区分点只有一个

 登录后的“状态”活在哪里?

这才是本质。


 Web 系统的“登录”

登录后发生什么?

image

服务器这边:

  • ❌ 不保存“你在线”

  • ❌ 不维护“你当前状态”

  • ❌ 不知道你是否在线

服务器只做一件事:

验证 token 是否有效


用户“下线”是什么意思?

在 Web 系统中:

  • 只是客户端删 token

  • 或 token 过期

  • 或 refresh token 失效

服务器并没有一个“用户对象”。

 Web 登录本质是:

身份校验机制,不是会话生命周期。


游戏服的“登录 / 下线”

对比一下

 

image

 

服务器内存中真实存在:

Dictionary<long, Player>
  • Player 有血量

  • 有位置

  • 有状态

  • 有技能 CD

  • 有房间引用

👉 这才叫“在线”。


 所以真正的分水岭是这条线

问题WebAPI游戏服
是否有 token
是否有在线表
是否有 Player 对象
是否有世界状态
服务器是否感知在线

Web 系统“不知道你在不在”。
游戏服“必须知道你在不在”。

九、是否维护“业务推进所必须的连续状态”

是是否需要常驻对象的分界线。

 (1)什么叫“维护对象”?

“维护对象”不是指:

  • 有 UserId

  • 有 nickname

  • 有 onlineTime

  • 有统计字段

这些都不是对象生命周期


以下都不算“对象状态”

这些只是属性数据

类型举例
用户资料 昵称、头像
统计 在线时长
累计 登录次数
行为记录 最近一次访问

它们有一个共同点👇

你随时可以从数据库算出来。

即使服务重启:

  • 不影响业务正确性

  • 不影响流程继续


真正的“对象状态”指什么?

我们来看真正需要对象的东西。


 对象状态 = 推进业务所必需的“过程状态”

例如:

游戏服里的 Player

当前房间 当前位置 血量 技能 CD BUFF 战斗目标 当前操作

这些状态:

  • 强关联

  • 实时变化

  • 必须连续

  • 一旦丢失 → 游戏崩

👉 这些不能只靠数据库恢复

这才叫:

对象状态(Process State)


一句话区分(非常重要)

如果状态丢了,业务还能不能继续?

  • 能 → 数据状态

  • 不能 → 对象状态


 Web 系统里的“状态”

我们来看你关心的那些。


在线时长

  • 累计数

  • 可补算

  • 可延迟写库

     ❌ 不需要对象


 是否在线

  • 最近 5 分钟是否活跃

  • TTL 机制

 ❌ 不需要对象


是否正在生成图片

  • task.status = processing

  • 可重试

  • 可恢复

 ❌ 不需要对象


用户当前在哪一步

例如:

 
已上传照片 → 已下单 → 已支付 → 已生成

这些都是:

  • 状态机

  • 离散状态

  • 可落库

 ❌ 不需要对象


(2)什么时候“必须有对象”?

 判断公式

状态是否依赖“上一次内存中的状态”才能继续?

如果:

  • 当前逻辑 = f(上一次内存状态)

  • 而不是 = f(数据库状态)

那你就进入了常驻对象领域


(3)举例对比

Web 业务:

当前状态 = 查数据库

游戏逻辑:

当前状态 = 上一帧内存状态 + 本次操作

这是本质区别。

 

能不能“幂等重放”?

  • Web 请求:可以

  • 游戏帧:不可以

为什么?

因为游戏的状态是:

连续不可重放的。


(4)状态分界表

状态类型是否需要对象
用户资料
统计字段
登录态
活跃时间
任务状态
流程步骤
房间
战斗
实时操作
帧同步
技能 CD
Buff

数据状态(Data State)

  • 可存储

  • 可恢复

  • 可延迟

  • 可重复

       Web 世界


过程状态(Process State)

  • 实时

  • 连续

  • 不可重建

  • 强顺序

👉 游戏世界

 

凡是可以“通过查库恢复”的状态,都不该存在内存对象中。

如果服务重启后还能继续业务,那就不该有常驻对象。

凡是依赖“在线对象 + 实时事件”的系统,都是常驻对象模型。

 

十、Newlife框架与IIS冲突的根本原因-线程池线程调度机制

NewLife 在内部假设:

  • 线程是“我的”

  • Timer 是“长期存在的”

  • 内存对象是“永不销毁的”

而 IIS / ASP.NET Core 的假设是:

  • 线程是“线程池共享的”

  • 请求必须“快速归还线程”

  • 后台逻辑不能无限生长

这两套假设正面冲突

iis请求进不来的真实原因不是内存泄露而是线程池被吃光。

IIS: 线程你用完就还
NewLife: 线程我先占着
IIS 没有能力区分:

“这是后台线程”

“这是请求线程”

在 .NET 里:

ThreadPool 就是一个池。

谁都从这里拿。

(1)为什么同样是吃线程池的线程,游戏服没有问题,但是IIS会出现问题

  •   关键是谁在等线程

IIS 场景:

客户端请求 ↓ IIS 请求队列 ↓ ThreadPool

如果线程池没线程:

👉 请求 直接卡在入口

用户看到的是:

  • 请求超时

  • 503

  • 进不来

这是致命的


游戏服场景:

image

 

即使线程池紧张:

  • socket 已经连上

  • 连接没断

  • 世界还在

用户最多感觉:

  • 延迟高

  • 卡顿

  • 心跳慢

但:

不会出现“新连接完全进不来”的情况

这是非常关键的区别。

  • 游戏服不是“每个请求一个线程”

WebAPI 模型:

 
1 个 HTTP 请求 = 1 个线程(哪怕很短)

你并发 1000:

👉 至少 1000 个线程争抢


游戏服务器模型:

1 个房间 1 个世界 1 个逻辑线程

无论:

  • 10 人

  • 1000 人

  • 1 万人

👉 逻辑线程数量是固定的。

客户端只是:

发消息 → 入队 → 等处理

不是:

来一个就抢一个线程

线程池耗尽不是问题本身,
“谁在等线程”才是问题。

  • WebAPI:入口在等线程 → 直接死亡

  • 游戏服:内部逻辑在等 → 只是变慢

  • .NET 的线程分类

1️⃣ IOCP 线程(I/O Completion)
2️⃣ Worker 线程(ThreadPool Worker)
3️⃣ 用户自己 new Thread 的线程

a.IOCP 是什么?(只负责“通知”)

IOCP(I/O Completion Port)是 Windows 内核机制。

它的作用只有一句话:

“告诉你:IO 完成了。”

比如:

  • socket 收到数据

  • socket 发完数据

  • 文件读完

⚠️ 注意:

IOCP 不跑业务逻辑

它只干这个:

 
内核 → 投递一个完成事件

然后:

 
.NET Runtime 把这个事件转给线程池

b.NET 线程池其实分两类线程(关键)

.NET ThreadPool 内部有两种线程:

image

 

🔹 IOCP 线程

  • 专门处理 IO 完成回调

  • 非常少(通常几十)

  • 不跑你的 Controller

  • 不跑业务逻辑

作用:

 
socket 收到数据了” “HTTP 包读完了”

👉 只通知,不处理。


🔹 Worker 线程(重点)

这才是:

  • Controller

  • Middleware

  • Action

  • 业务逻辑

真正运行的线程。

你写的代码:

 
public async Task<IActionResult> Get() { DoSomething(); }

👉 最终一定是在 Worker 线程上执行的。

c.WebAPI 一个请求完整走一遍(你一定要看)

image

 

🔥 关键点在这里:

Controller 永远跑在 Worker Thread 上。

d.async / await 并不是“不用线程”

这是很多人最大的误区。

async 的真实含义是

“执行过程中如果遇到 IO,我把线程还回池子。”

流程是:

image

image

 e.new Thread() 创建的线程,根本不属于 ThreadPool。

哪怕你在 ASP.NET 里调用它,也一样。

它是:

  • OS 原生线程

  • CLR 注册的托管线程

  • 不是 ThreadPool Worker Thread

这是 .NET 运行时层面的硬区分。

image

 ThreadPool Worker Thread:

ThreadPool.QueueUserWorkItem(...)
Task.Run(...)
async/await 的 continuation
用的线程。

特点:

数量有限

CLR 自动管理

给 Web / async / 并发任务用

WebAPI 的命根子

IIS 的所有请求都靠它。

new Thread():

 

new Thread(GameLoop).Start();
发生的是👇

 

1️⃣ CLR 调用 Windows API
text
复制代码
CreateThread
2️⃣ 操作系统创建一个真实线程
有自己栈

 

有自己 TEB

 

有自己调度

 

不在线程池里

 

3️⃣ CLR 只是“登记它是托管线程”
但:

 

CLR 不会把它放进 ThreadPool。

 

🔥 重点来了(一定要看)
ThreadPool 线程
和 new Thread 线程
在运行时是完全两套体系。

 

它们唯一共同点:

 

都是 OS 线程

 

都受 CPU 调度

 

但:

 

对比ThreadPool Workernew Thread
是否属于线程池
IIS 是否使用
请求是否靠它
是否会耗尽 Web 请求能力
是否自动回收
是否长期运行

 

(2)newlife框架使用的线程池线程最终会趋于稳定,为什么调整线程池数量上限解决不了newlife应用于IIS时线程被吃掉,请求线程进不来的问题

 

posted @ 2026-01-19 15:51  头号程序媛  阅读(3)  评论(0)    收藏  举报