gpt4 book ai didi

c# - 使用 .Net HttpListener 的多线程

转载 作者:IT王子 更新时间:2023-10-29 04:17:45 30 4
gpt4 key购买 nike

我有一个听众:

listener = new HttpListener();
listener.Prefixes.Add(@"http://+:8077/");
listener.Start();
listenerThread = new Thread(HandleRequests);
listenerThread.Start();

我正在处理请求:

private void HandleRequests()
{
while (listener.IsListening)
{
var context = listener.BeginGetContext(new AsyncCallback(ListenerCallback), listener);
context.AsyncWaitHandle.WaitOne();
}
}

private void ListenerCallback(IAsyncResult ar)
{
var listener = ar.AsyncState as HttpListener;

var context = listener.EndGetContext(ar);

//do some stuff
}

我想以这样的方式编写 void Stop():

  1. 它将阻塞直到所有当前处理的请求结束(即等待所有线程“做一些事情”)。
  2. 虽然它会等待已经开始的请求,但它不会允许任何更多请求(即在 ListenerCallback 开始时返回)。
  3. 之后它将调用 listener.Stop()(listener.IsListening 变为 false)。

怎么写呢?

编辑:您如何看待这个解决方案?安全吗?

public void Stop() 
{
lock (this)
{
isStopping = true;
}
resetEvent.WaitOne(); //initially set to true
listener.Stop();
}

private void ListenerCallback(IAsyncResult ar)
{
lock (this)
{
if (isStopping)
return;

resetEvent.Reset();
numberOfRequests++;
}

var listener = ar.AsyncState as HttpListener;

var context = listener.EndGetContext(ar);

//do some stuff

lock (this)
{
if (--numberOfRequests == 0)
resetEvent.Set();
}
}

最佳答案

为了完整起见,如果您管理自己的工作线程,情况如下:

class HttpServer : IDisposable
{
private readonly HttpListener _listener;
private readonly Thread _listenerThread;
private readonly Thread[] _workers;
private readonly ManualResetEvent _stop, _ready;
private Queue<HttpListenerContext> _queue;

public HttpServer(int maxThreads)
{
_workers = new Thread[maxThreads];
_queue = new Queue<HttpListenerContext>();
_stop = new ManualResetEvent(false);
_ready = new ManualResetEvent(false);
_listener = new HttpListener();
_listenerThread = new Thread(HandleRequests);
}

public void Start(int port)
{
_listener.Prefixes.Add(String.Format(@"http://+:{0}/", port));
_listener.Start();
_listenerThread.Start();

for (int i = 0; i < _workers.Length; i++)
{
_workers[i] = new Thread(Worker);
_workers[i].Start();
}
}

public void Dispose()
{ Stop(); }

public void Stop()
{
_stop.Set();
_listenerThread.Join();
foreach (Thread worker in _workers)
worker.Join();
_listener.Stop();
}

private void HandleRequests()
{
while (_listener.IsListening)
{
var context = _listener.BeginGetContext(ContextReady, null);

if (0 == WaitHandle.WaitAny(new[] { _stop, context.AsyncWaitHandle }))
return;
}
}

private void ContextReady(IAsyncResult ar)
{
try
{
lock (_queue)
{
_queue.Enqueue(_listener.EndGetContext(ar));
_ready.Set();
}
}
catch { return; }
}

private void Worker()
{
WaitHandle[] wait = new[] { _ready, _stop };
while (0 == WaitHandle.WaitAny(wait))
{
HttpListenerContext context;
lock (_queue)
{
if (_queue.Count > 0)
context = _queue.Dequeue();
else
{
_ready.Reset();
continue;
}
}

try { ProcessRequest(context); }
catch (Exception e) { Console.Error.WriteLine(e); }
}
}

public event Action<HttpListenerContext> ProcessRequest;
}

关于c# - 使用 .Net HttpListener 的多线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4672010/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com