2013-03-14 1 views
4

J'ai une application qui utilise la classe HttpListener dans .Net 4.0 pour traiter les requêtes http.Modification de la limite de la file d'attente du noyau HTTP.sys lors de l'utilisation de .Net HttpListener?

En charge, j'ai remarqué que je reçois 503 - QueueFull - erreurs rapportées dans le journal. Une recherche de cette erreur suggère qu'il se produit lorsque le nombre maximal de demandes que la file d'attente http.sys a été dépassé.

La longueur de la file d'attente par défaut est 1000. Si vous utilisez IIS cela semble être ajustable via le paramètre "Longueur de la file d'attente" dans les paramètres avancés du pool d'applications.

Si vous êtes PAS de en utilisant IIS est-il possible de régler cette valeur? Ou est le contrôle de ce paramètre caché dans la classe HttpListener et non exposé aux développeurs?

+0

Avez-vous essayé de définir la clé de registre 'HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft \ ASP.NET \ 4.0.30319.0 \ MaxConcurrentRequestsPerCPU' quelque chose de plus grand? (http://blogs.msdn.com/b/tmarq/archive/2007/07/21/asp-net-thread-usage-on-iis-7-0-and-6-0.aspx) ou l'un des les entrées de registre ici http://support.microsoft.com/kb/820129 –

+0

Merci pour la réponse Chris. Je n'ai pas encore eu l'occasion d'essayer les paramètres, cependant, le blog suggère que la file d'attente du noyau http.sys est différente de ce que MaxConcurrentRequestsPerCPU affecte. J'ai regardé les paramètres de registre pour http.sys avant et aucune des descriptions ne dit qu'ils vont modifier la longueur de la file d'attente –

Répondre

7

Il semble que le HttpListener ne permet pas de changer le HttpServerQueueLengthProperty propriété directement. Et by default this property is set to 1000.

Mais vous pouvez essayer de le définir manuellement après HttpListener démarrer. Il est bidouille, car il utilise la propriété interne RequestQueueHandle de HttpListener, donc utiliser à vos risques et périls.

Hack:

using System; 
using System.Linq; 
using System.Net; 
using System.Reflection; 
using System.Runtime.InteropServices; 

namespace Network.Utils 
{ 
    public static class HttpApi 
    { 
     public unsafe static void SetRequestQueueLength(HttpListener listener, long len) 
     { 
      var listenerType = typeof (HttpListener); 
      var requestQueueHandleProperty = listenerType.GetProperties(BindingFlags.NonPublic | BindingFlags.Instance).First(p => p.Name == "RequestQueueHandle"); 

      var requestQueueHandle = (CriticalHandle)requestQueueHandleProperty.GetValue(listener); 
      var result = HttpSetRequestQueueProperty(requestQueueHandle, HTTP_SERVER_PROPERTY.HttpServerQueueLengthProperty, new IntPtr((void*)&len), (uint)Marshal.SizeOf(len), 0, IntPtr.Zero); 

      if (result != 0) 
      { 
       throw new HttpListenerException((int) result); 
      } 
     } 

     internal enum HTTP_SERVER_PROPERTY 
     { 
      HttpServerAuthenticationProperty, 
      HttpServerLoggingProperty, 
      HttpServerQosProperty, 
      HttpServerTimeoutsProperty, 
      HttpServerQueueLengthProperty, 
      HttpServerStateProperty, 
      HttpServer503VerbosityProperty, 
      HttpServerBindingProperty, 
      HttpServerExtendedAuthenticationProperty, 
      HttpServerListenEndpointProperty, 
      HttpServerChannelBindProperty, 
      HttpServerProtectionLevelProperty, 
     } 

     [DllImport("httpapi.dll", CallingConvention = CallingConvention.StdCall, SetLastError = true)] 
     internal static extern uint HttpSetRequestQueueProperty(
      CriticalHandle requestQueueHandle, 
      HTTP_SERVER_PROPERTY serverProperty, 
      IntPtr pPropertyInfo, 
      uint propertyInfoLength, 
      uint reserved, 
      IntPtr pReserved);   
    } 
} 

Exemple d'utilisation:

using (var listener = new HttpListener()) 
{ 
    listener.Prefixes.Add("http://*:8080/your/service/"); 
    listener.Start(); 

    Network.Utils.HttpApi.SetRequestQueueLength(listener, 5000); 

    // ... 
} 

Après démarrage de l'application, vous pouvez vérifier la longueur de la file d'attente en exécutant cette commande:

netsh http show servicestate 

Vérifiez la propriété "Max demande" pour votre processus. Maintenant, il doit être égal à 5000.

Questions connexes