使用多线程处理HttpListener多请求出现异常行为该如何解决
问题原因
- 缺失
Content-Length响应头:浏览器无法判断HTTP响应的传输结束边界,会一直等待连接超时,导致部分请求呈现挂起状态。 - 浏览器缓存策略影响:Chrome默认对相同URL的GET请求会启用缓存,多个相同请求会复用已返回的响应结果,因此出现内容重复的现象。
- 无异常捕获逻辑:如果请求处理过程中抛出未被捕获的异常,会导致对应请求无法正常返回响应,连接一直被占用。
修复方案
修改后的完整代码如下:
using System; using System.Text; using System.Net; using System.Threading; class Program { static void Main(string[] args) { HttpListener listener = new HttpListener(); listener.Prefixes.Add("http://localhost:5001/"); listener.Start(); Console.WriteLine("服务已启动,监听端口5001"); Listen(listener); } static void Listen(HttpListener listener) { while (true) { var context = listener.GetContext(); Thread backgroundThread = new Thread(() => HandleContext(context)); backgroundThread.IsBackground = true; backgroundThread.Start(); } } static void HandleContext(HttpListenerContext context) { try { Thread.Sleep(5000); Console.WriteLine($"请求处理完成,时间:{DateTime.Now},请求地址:{context.Request.Url}"); var responseContent = "Hello world"; var buffer = Encoding.UTF8.GetBytes(responseContent); // 显式设置必要的响应头 context.Response.ContentType = "text/plain; charset=utf-8"; context.Response.ContentLength64 = buffer.Length; context.Response.Headers.Add("Cache-Control", "no-cache, no-store, must-revalidate"); context.Response.StatusCode = 200; context.Response.OutputStream.Write(buffer, 0, buffer.Length); } catch (Exception ex) { context.Response.StatusCode = 500; var errorBuffer = Encoding.UTF8.GetBytes($"服务器错误:{ex.Message}"); context.Response.OutputStream.Write(errorBuffer, 0, errorBuffer.Length); } finally { // 无论处理是否异常都正常关闭响应释放连接 context.Response.OutputStream.Close(); context.Response.Close(); } } }
如果需要验证并发处理效果,可在三个标签页分别访问带不同参数的地址,比如http://localhost:5001/?t=1、http://localhost:5001/?t=2、http://localhost:5001/?t=3,避免浏览器的请求合并策略影响测试结果。
内容的提问来源于stack exchange,提问作者Do Tran
相关产品推荐
相关产品推荐

