.NET线程数无硬编码上限,实际受限于操作系统内存与内核对象;默认1MB栈空间导致32位进程约2000线程即OOM,64位受物理内存与页表限制;应优先使用async/await和ThreadPool而非手动创建大量Thread。

线程数受操作系统和内存限制,不是 .NET 硬编码上限
.NET 本身不设固定线程数量上限,ThreadPool 默认最大线程数由 ThreadPool.GetMaxThreads 返回,但这个值只是线程池的“软限制”,实际能创建多少个 Thread 实例,取决于 Windows(或 Linux/macOS)能为该进程分配多少栈空间和内核对象。
每个线程默认占用 1MB 栈空间,内存很快见底
在 Windows 上,.NET 的 Thread 默认栈大小是 1 MB(x64 进程),哪怕只调用 new Thread(() => {}).Start(),也会立即向进程地址空间申请这块保留内存(commit 按需)。32 位进程用户态地址空间仅约 2GB,理论上撑不过 2000 个线程;64 位进程虽大得多,但物理内存和页表开销会先成为瓶颈。常见现象是:创建几百个线程后,OutOfMemoryException 或 Thread.Start() 抛出 InvalidOperationException(内部触发 ERROR_NOT_ENOUGH_MEMORY)。
-
Thread构造时可通过new Thread(..., stackSize)指定更小栈(如256 * 1024),但低于 128KB 可能导致 StackOverflow - 频繁创建/销毁线程比复用
ThreadPool或Task开销大得多,且易触发 GC 压力 - Windows 内核对每个进程的线程句柄数也有默认限制(通常 2000–4000),可通过
SetProcessInformation调整,但极少需要
别硬扛线程数,改用异步 I/O 和 Task 调度
真正需要“高并发”的场景(如万级连接的服务器),几乎从不依赖大量 Thread 实例。正确做法是:用 async/await + SocketAsyncEventArgs(或 System.Net.Sockets.Socket 的异步方法),让单线程处理数百连接;CPU 密集任务则交由 Task.Run 并依赖 ThreadPool 自动伸缩(其最大线程数默认为 Environment.ProcessorCount * 100,但会按负载动态调整)。
千博购物系统.Net能够适合不同类型商品,为您提供了一个完整的在线开店解决方案。千博购物系统.Net除了拥有一般网上商店系统所具有的所有功能,还拥有着其它网店系统没有的许多超强功能。千博购物系统.Net适合中小企业和个人快速构建个性化的网上商店。强劲、安全、稳定、易用、免费是它的主要特性。系统由C#及Access/MS SQL开发,是B/S(浏览器/服务器)结构Asp.Net程序。多种独创的技术使
var tasks = Enumerable.Range(0, 10000)
.Select(_ => Task.Run(() => HeavyComputation()))
.ToArray();
await Task.WhenAll(tasks); // 实际并发执行数远小于 10000,由线程池控制检查当前限制和实际使用量的方法
运行时可快速验证当前环境约束:
- 查线程池上限:
ThreadPool.GetMaxThreads(out int workerThreads, out int completionPortThreads) - 查已启动线程数(粗略):
Process.GetCurrentProcess().Threads.Count(注意:包含调试器、GC、JIT 等后台线程) - 观察私有字节(Private Bytes)增长:每新增一个默认栈线程,进程内存上升约 1MB(保留区)
真要突破几百线程,先确认是否误用了同步阻塞模型——这是绝大多数“需要更多线程”诉求的根源。









