2

我有一个服务器使用 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。

4

0 回答 0