簡體   English   中英

C# HttpListener 處理多線程請求

[英]C# HttpListener handling requests with multiple threads

我必須申請2個方法:

  1. 使用不同的線程/任務處理每個 HTTP 請求。
  2. 在調用取消令牌時優雅地完成請求。

現在,我有一個問題,當調用取消令牌並且請求沒有到達時 - 我在“server.getContext”阻塞區域中堆疊。 知道如何解決嗎?

public void Listen()
{
  CancellationTokenSource source = new CancellationTokenSource();
  CancellationToken token = source.Token;
  server.Start();
  Console.WriteLine($"Waiting for connections on {url}");
  HandleShutdownWhenKeyPressed(source);
  HandleIncomingHTTPRequests(token);
  server.Close();
}

void HandleIncomingHTTPRequests(CancellationToken token)
{
  while (!token.IsCancellationRequested)
  {
    HttpListenerContext ctx = server.GetContext();
    // I stack here until the request has arrived even if the cancellation token has invoked.
    Task.Run(() =>
    {
      HttpListenerRequest req = ctx.Request;
      HttpListenerResponse res = ctx.Response;
      // SOME STUFF ....
    },token)
  }
 }

提前致謝。

您不需要Task.Runasync IO 的美妙之處在於您不需要自己處理ThreadThreadPoolTask.Run :實際實現已經為您處理了 IO 完成(在這種情況下, HttpListener ,但在其他情況下,它可能是FileStreamSocket等)。

你只需要這樣:

public static async Task RunHttpListenerAsync( HttpListener listener, CancellationToken ct )
{
    listener.Start();

    while( !ct.IsCancellationRequested )
    {
        HttpListenerContext ctx = await listener.GetContextAsync().ConfigureAwait(false);
        
        try
        {
            await ProcessRequestAsync( ctx ).ConfigureAwait(false);
        }
        catch( Exception ex )
        {
            // TODO: Log `ex`.
        }
    }
}

private static async Task ProcessRequestAsync( HttpListenerContext ctx )
{
    HttpListenerRequest  req = ctx.Request;
    HttpListenerResponse res = ctx.Response;

    // do stuff
}

如果您的程序在沒有需要在單個線程上恢復的同步上下文的情況下運行(即您沒有在 WinForms 或 WPF 中運行) - 或者 -您在任何地方使用.ConfigureAwait(false)就像您應該的那樣)然后每次您的程序屈服於調度程序它將在它想要的線程池中的任何后台線程上恢復,包括將同時恢復當前Task的任何可用線程。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM