C#摄像头图像控制器MJPEG流阻塞其他API请求问题求助
故障原因
- ASP.NET Session串行锁限制:默认ASP.NET对同一会话的所有请求会串行执行,视频流接口是长连接会一直持有Session锁,导致Left、Right等同会话下的其他请求只能排队等待,直到流请求释放锁才会执行,直接造成1-3分钟的阻塞。
- MJPEG帧格式不完整:你代码里
WriteFrameAsync方法中,帧末尾的\r\n结束标识写入代码被注释了,浏览器无法识别单帧结束边界,会一直认为响应未完成,导致视频流请求持续挂着不释放连接。 - 浏览器同域名并发连接限制:Chrome、Edge等浏览器对同域名默认最多支持6个并发TCP连接,长连接的视频流会长期占用一个连接名额,当连接占满后后续请求就会排队等待。
- 资源管理缺陷:ApiController是每次请求新建实例,你将
MJPEGStream、WebClient作为实例变量,每次请求都会新建一个到摄像头的拉流连接,不仅会占满摄像头的连接配额,还容易引发服务端端口、资源泄漏,进一步加剧阻塞。
解决方法
禁用控制器Session锁
在CameraController类上添加[SessionState(SessionStateBehavior.Disabled)]特性,你当前控制器未使用Session功能,禁用后同会话请求可以并行执行,直接解决串行阻塞问题。修复MJPEG帧格式
恢复WriteFrameAsync方法中被注释的footer写入代码:
await stream.WriteAsync(footer, 0, footer.Length);
确保每个JPEG帧都有完整的结束标识,浏览器可以正确拆分帧,不会持续挂起连接。
- 优化并发连接策略
- 条件允许的话将服务端升级到HTTP/2协议,HTTP/2支持同域名多路复用,不会有6个并发连接的限制;
- 也可以将视频流接口和PTZ控制接口拆分到不同域名,避开同域名连接数限制。
- 优化资源管理
- 将
MJPEGStream改为单例模式,所有请求共用同一个摄像头拉流实例,避免重复创建拉流连接浪费资源; - 把
WebClient替换为线程安全的HttpClient全局单例复用,避免频繁创建销毁WebClient导致的端口耗尽问题。
- 完善异常处理
在StartStream的循环异常捕获中添加退出逻辑,不要空吞异常导致连接长期挂死,出现异常时直接终止流、释放资源。
内容的提问来源于stack exchange,提问作者Richard Housham
相关产品推荐
相关产品推荐

