I Définissez le fil max sur 10. Puis j'ai ajouté 22000 tâches en utilisant ThreadPool.QueueUserWorkItem. Il est très probable que toutes les 22 000 tâches ne soient pas terminées après avoir exécuté le programme. Y a-t-il une limitation du nombre de tâches peut être mise en file d'attente pour des threads disponibles? P>
4 Réponses :
La file d'attente n'a aucune limite pratique, mais la piscine elle-même ne dépassera pas 64 poignées d'attente, c'est-à-dire des threads totaux actifs. P>
Un bug a causé mon problème, mais la réponse de la question est-elle essentiellement.
Merci @keith. Il semble donc que la seule limite réelle à la taille de la file d'attente est la taille d'une file d'attente générique (ou similaire) elle-même.
du Documentation de ThreadPool : < / p>
Remarque: strong> Les threads dans la piscine de thread gérée sont des filets de fond. C'est-à-dire que leurs propriétés d'isbackground sont vraies. Cela signifie qu'un thread de threadpool ne conserve pas une application en cours d'exécution après tous les fils de premier plan. P> blockQuote> est-il possible que vous sortiez avant que toutes les tâches aient été traitées? P>
Il s'agit d'une question dépendante de la mise en œuvre et de la mise en œuvre de cette fonction a changé un peu au fil du temps. Mais dans .NET 4.0, vous êtes essentiellement limité par la quantité de mémoire dans le système car les tâches sont stockées dans une file d'attente en mémoire. Vous pouvez la voir en creusant la mise en œuvre dans le réflecteur. P>
Si vous avez besoin d'attendre toutes les tâches de traiter, vous devez vous gérer vous-même. Les filetages de threadpool sont toutes des fils de fond et ne conservent pas l'application vivante.
Ceci est un moyen relativement propre pour gérer ce type de situation: P>
using (var mre = new ManualResetEvent(false)) { int remainingToProcess = workItems.Count(); // Assuming workItems is a collection of "tasks" foreach(var item in workItems) { // Delegate closure (in C# 4 and earlier) below will // capture a reference to 'item', resulting in // the incorrect item sent to ProcessTask each iteration. Use a local copy // of the 'item' variable instead. // C# 5/VS2012 will not require the local here. var localItem = item; ThreadPool.QueueUserWorkItem(delegate { // Replace this with your "work" ProcessTask(localItem); // This will (safely) decrement the remaining count, and allow the main thread to continue when we're done if (Interlocked.Decrement(ref remainingToProcess) == 0) mre.Set(); }); } mre.WaitOne(); }
Bonne idée, mais l'application attendait toutes les discussions. Le groupement est également une très bonne suggestion.