Je suis lecture sur AsyncControllers dans ASP.NET MVC.
Il semble que la seule raison pour laquelle ils existent est que les threads IIS peuvent être enregistrés tandis que le travail de longue durée est délégué aux threads CLR normaux, qui semblent être moins chers.
J'ai quelques questions ici:
ASP.NET traite les demandes à l'aide de threads du pool de threads .NET. Le pool de threads conserve un pool de threads qui ont déjà encouru les coûts d'initialisation des threads. Par conséquent, ces fils sont faciles à réutiliser. Le pool de threads .NET s'auto-ajuste également. Il surveille l'utilisation du processeur et d'autres ressources et ajoute de nouveaux threads ou ajuste la taille du pool de threads selon les besoins. Vous devez généralement éviter de créer des threads manuellement pour effectuer le travail. Utilisez plutôt des threads du pool de threads. Dans le même temps, il est important de s'assurer que votre application n'effectue pas de longues opérations de blocage qui pourraient rapidement entraîner une famine du pool de threads et rejeter les requêtes HTTP.
Les E/S disque, les appels de service Web, sont tous bloquants. Il est préférable d'optimiser l'utilisation d'appels asynchrones. Lorsque vous effectuez un appel asynchrone, asp.net libère votre thread et la demande sera affectée à un autre thread lorsque la fonction de rappel est invoquée.
Pour configurer le nombre de threads, vous pouvez définir:
<system.web>
<applicationPool maxConcurrentRequestsPerCPU="50" maxConcurrentThreadsPerCPU="0" requestQueueLimit="5000"/>
</system.web>
Reportez-vous: tilisation du thread ASP.NET sur IIS 7.5, IIS 7.0 et IIS 6. =
Ce sont les paramètres qui les meilleures pratiques Microsoft recommandent :
Remarque : Les recommandations fournies dans cette section ne sont pas des règles. Ils sont un point de départ.
Vous devrez comparer votre application pour trouver ce qui fonctionne le mieux pour votre application.
Les threads IIS sont extraits du pool de threads par défaut, qui est limité par défaut en fonction du nombre de cœurs de processeur. Si cette file d'attente du pool de threads est sauvegardée, IIS cessera de répondre aux demandes. En utilisant du code asynchrone, le thread du pool de threads peut être renvoyé au pool pendant que l'opération asynchrone a lieu, permettant à IIS de traiter plus de demandes dans l'ensemble.
D'un autre côté, la création d'un nouveau thread par vous-même n'utilise pas de thread de pool de threads. La génération d'un nombre non contrôlé de threads indépendants peut également être un problème, donc ce n'est pas une solution miracle au problème du pool de threads IIS. Async IO est généralement préféré dans les deux cas.
Quant à la modification du nombre de threads dans le pool de threads, cochez ici . Cependant, vous devriez probablement vraiment éviter de le faire.
Notre Webservice a besoin de temps en temps de servir 100 requets/seconde tandis que le reste du temps c'est 1 requête/seconde. Analazyng IIS logs nous avons découvert qu'il fallait environ 28s quand une rafale se produit pour servir de tels appels.
L'application de meilleures pratiques Microsoft comme cité par @nunespascal a considérablement réduit le temps à 1 s dans notre cas.
Vous trouverez ci-dessous le script Powershell que nous utilisons actuellement lorsque nous déployons nos serveurs de production. Il met à jour machine.config en tenant compte du nombre de processeurs logiques.
<# Get and backup current machine.config #>
$path = "C:\Windows\Microsoft.Net\Framework\v4.0.30319\Config\machine.config";
$xml = [xml] (get-content($path));
$xml.Save($path + "-" + (Get-Date -Format "yyyyMMdd-HHmm" ) + ".bak");
<# Get number of physical CPU #>
$physicalCPUs = ([ARRAY](Get-WmiObject Win32_Processor)).Count;
<# Get number of logical processors #>
$logicalProcessors = (([ARRAY](Get-WmiObject Win32_Processor))[0] | Select-Object “numberOfLogicalProcessors").numberOfLogicalProcessors * $physicalCPUs;
<# Set Number of connection in system.net/connectionManagement #>
$systemNet = $xml.configuration["system.net"];
if (-not $systemNet){
$systemNet = $xml.configuration.AppendChild($xml.CreateElement("system.net"));
}
$connectionManagement = $systemNet.connectionManagement;
if (-not $connectionManagement){
$connectionManagement = $systemNet.AppendChild($xml.CreateElement("connectionManagement"));
}
$add = $connectionManagement.add;
if(-not $add){
$add = $connectionManagement.AppendChild($xml.CreateElement("add")) ;
}
$add.SetAttribute("address","*");
$add.SetAttribute("maxconnection", [string]($logicalProcessors * 12) );
<# Set several thread settings in system.web/processModel #>
$systemWeb = $xml.configuration["system.web"];
if (-not $systemWeb){
$systemWeb = $xml.configuration.AppendChild($xml.CreateElement("system.web"));
}
$processModel = $systemWeb.processModel;
if (-not $processModel){
$processModel = $systemWeb.AppendChild($xml.CreateElement("processModel"));
}
$processModel.SetAttribute("autoConfig","true");
$processModel.SetAttribute("maxWorkerThreads","100");
$processModel.SetAttribute("maxIoThreads","100");
$processModel.SetAttribute("minWorkerThreads","50");
$processModel.SetAttribute("minIoThreads","50");
<# Set other thread settings in system.web/httRuntime #>
$httpRuntime = $systemWeb.httpRuntime;
if(-not $httpRuntime){
$httpRuntime = $systemWeb.AppendChild($xml.CreateElement("httpRuntime"));
}
$httpRuntime.SetAttribute("minFreeThreads",[string]($logicalProcessors * 88));
$httpRuntime.SetAttribute("minLocalRequestFreeThreads",[string]($logicalProcessors * 76));
<#Save modified machine.config#>
$xml.Save($path);
Cette solution nous est venue d'un blog article rédigé par Stuart Brierley en 2009. Nous l'avons testé avec succès avec Windows Server de 2008 R2 à 2016.
En fait, ce qui est écrit en article que vous avez lié n'est pas vrai. Le modèle asynchrone n'est pas là pour libérer "super coûteux IIS Worker Threads" et utiliser en arrière-plan d'autres "threads bon marché".
Le modèle asynchrone est là simplement pour libérer les threads. Vous pouvez en bénéficier dans des scénarios où vous n'avez pas besoin de vos threads (et mieux même pas de votre machine locale).
Je peux nommer deux exemples de scénarios (les deux E/S):
Premier:
Et seconde presque identique:
Il est généralement sûr de lire msdn. Vous pouvez obtenir des informations sur le modèle asynchrone ici .