使用多线程处理多个http请求HttpListener导致奇怪的行为
Posted
技术标签:
【中文标题】使用多线程处理多个http请求HttpListener导致奇怪的行为【英文标题】:Handle multiple http request HttpListener using multithread leads to strange behavior 【发布时间】:2021-11-26 18:35:28 【问题描述】:我正在尝试创建一个 HttpListener
并接受 Http 请求,对于每个 HttpListenerContext
我创建一个专用线程来像这样处理它
while(true)
var context = listener.GetContext();
Thread backgroundThread = new Thread(() => HandleContext(context));
backgroundThread.Start();
在HandleContext
我做一个Thread.Sleep(5000)
来模拟工作和Console.WriteLine(DateTime.Now)
用于调试目的。
但是当我同时在 Chrome 中打开 3 个标签时,只有 2 个标签返回,但结果重复,最后一个标签一直挂着。
据我所知,我的线程没有可能导致死锁的共享数据,但这种行为似乎是死锁,你能告诉我我做错了什么以及如何解决它吗?
这是我的完整代码
class Program
private static HttpListener _listener;
static void Main(string[] args)
HttpListener listener = new HttpListener();
listener.Prefixes.Add("http://localhost:5001/");
listener.Start();
Listen(listener);
static void Listen(HttpListener listener)
while (true)
var context = listener.GetContext();
Thread backgroundThread = new Thread(() => HandleContext(context));
backgroundThread.Start();
static void HandleContext(HttpListenerContext context)
Thread.Sleep(5000);
Console.WriteLine($"Hello world, DateTime.Now");
var responseContent = "Hello world";
var buffer = Encoding.UTF8.GetBytes(responseContent);
context.Response.OutputStream.Write(buffer, 0, buffer.Length);
context.Response.OutputStream.Close();
context.Response.Close();
【问题讨论】:
您在static void Listen(HttpListener listener)
方法的开头有一个“孤儿”listener.GetContext();
。不会处理此上下文,这解释了您的标签“空”。
@Madhatter 能不能再具体点,context 是在backgroundThread 中传递的,线程是在同一个Context 范围内启动的,那为什么会是“孤儿”呢?
在您发布的代码中有两个listener.GetContext();
。第一个永远不会发送到HandleContext
方法
对不起,我的错。这不是我打算做的。但是 Console.WriteLine 仍然被复制
【参考方案1】:
过了一会儿,我发现类似“死锁”的行为是由于@Mat Hatter 指出的“孤儿”GetContext
而发生的。由于谷歌浏览器发送 2 个请求的行为,Console.WriteLine 被复制,1 个用于网站内容,1 个用于 fav.icon。因此,Console.WriteLine 被复制并没有错。
【讨论】:
【参考方案2】:您没有设置HttpListenerResponse
流的ContentLength64
属性!
请试试这个
context.Response.ContentLength64 = buffer.LongLength;
using (Stream stream = context.Response.OutputStream)
stream.Write(buffer, 0, buffer.Length);
【讨论】:
以上是关于使用多线程处理多个http请求HttpListener导致奇怪的行为的主要内容,如果未能解决你的问题,请参考以下文章