我有一个服务器使用 HttpListener.Listen() 监听请求,并支持使用 CancellationTokenSource.Token 取消。这是在 c# 4.0 上。调用代码:
Task.Factory.StartNew(() =>
{
myServer = new MyServer();
myServer.Listen(new[] { "http://*:8085/" }, cancel.Token);
});
我的服务器:
public void Listen(IEnumerable<string> prefixes, CancellationToken cancel)
{
httpListener = new HttpListener();
foreach(var p in prefixes) httpListener.Prefixes.Add(p);
httpListener.Start();
// watch for cancellation
while(!cancel.IsCancellationRequested)
{
var result = httpListener.BeginGetContext(callback =>
{
var listener = (HttpListener)callback.AsyncState;
if(!listener.IsListening) return;
var httpContext = listener.EndGetContext(callback);
// handle the request in httpContext, some requests can take some time to complete
}, httpListener);
while(result.IsCompleted == false)
{
if(cancel.IsCancellationRequested) break;
Thread.Sleep(100); // sleep and recheck
}
}
httpListener.Stop();
}
到目前为止,它似乎工作正常,但它似乎是一段过长的代码。我尝试这样使用 FromAsync() :
public void Listen(IEnumerable<string> prefixes, CancellationToken cancel)
{
httpListener = new HttpListener();
foreach(var p in prefixes) httpListener.Prefixes.Add(p);
httpListener.Start();
while(!cancel.IsCancellationRequested)
{
Task.Factory.FromAsync<HttpListenerContext>(httpListener.BeginGetContext, httpListener.EndGetContext, null).ContinueWith(t =>
{
var httpContext = t.Result;
// do stuff
}, cancel);
}
httpListener.Stop();
}
但发生的事情是我会很快耗尽内存,因为在 while 循环中创建了许多任务。有关如何解决此问题的任何建议?或者如何清理我的第一次尝试?我在其他一些线程上看到了一些答案,但是当我的项目在 .net 4.0 上时使用 .net 5.0。