2010-11-22 28 views
2

Je crée une application multi-thread utilisant des délégués pour gérer le traitement des demandes dans un service WCF. Je souhaite que les clients puissent envoyer la demande, puis se déconnecter et attendre un rappel pour annoncer que le travail est terminé (qui sera probablement effectué dans une base de données). Je ne sais pas combien de demandes peuvent être reçues en même temps, cela pourrait être une demande de temps à autre ou bien des dizaines de demandes. Pour autant que je sache, le pool d'unités d'exécution de .Net a 25 unités d'exécution disponibles. Que se passe-t-il lorsque je recrée 25 délégués ou plus? Est-ce qu'il lance une erreur, attend-il, met-il en pause une opération existante et commence à travailler sur le nouveau délégué, ou un autre comportement? Au-delà, que se passe-t-il si je veux générer jusqu'à 25 délégués alors que d'autres opérations (telles que les connexions entrantes/sortantes) veulent démarrer et/ou lorsqu'une autre opération fonctionne et que je veux générer une autre déléguer?En utilisant des délégués dans C# .Net, que se passe-t-il lorsque je n'ai plus de threads dans le pool de threads .Net?

Je veux m'assurer que c'est évolutif sans être trop complexe.

Merci

+0

Si vous utilisez WCF, vous n'avez pas la version 2.0 RTM de .NET. La limite est de 250 x nombre de cœurs de processeur. –

+0

Ce que je veux dire par souci de threads (et comment j'y accède) appelle des méthodes normalement synchrones via un délégué en utilisant BeginInvoke. Les goulots d'étranglement au niveau des performances sont probablement le fait que le client répondeur fait une chose (attendre une recherche dans la base de données) puis, éventuellement, renvoyer une grande quantité de données et le temps nécessaire pour l'envoyer via Internet au service de courtier central. au client demandeur. –

+0

Je suis actuellement en train de développer ceci dans .Net 3.5, bien que je puisse passer à 4.0 s'il semble qu'il offre des fonctionnalités/performances dont j'ai besoin pour mon application (et WCF en particulier). –

Répondre

4

Toutes les opérations sont mises en attente (je suppose que vous utilisez le threadpool directement ou indirectement). C'est le travail du pool de threads de grignoter la file d'attente et de répartir les opérations sur les threads. Éventuellement, tous les threads peuvent être occupés, ce qui signifie simplement que la file d'attente va augmenter jusqu'à ce que les threads soient libres de commencer à traiter les éléments de travail mis en file d'attente.

+0

J'appelle BeginInvoke d'un délégué pointant vers une méthode. (Ma connaissance du multithreading est très limitée.J'ai lu pas mal de choses la semaine dernière et je sais comment mettre en œuvre mon objectif de différentes manières, mais je ne comprends pas complètement les implications de cela, et les délégués semblent être la manière la plus facile de rendre le processus asynchrone). –

+1

@Chris L'appel de BeginInvoke va en effet utiliser le ThreadPool indirectement. Toutes les opérations sont mises en file d'attente et les unités d'exécution disponibles prennent des éléments de la file d'attente. S'il n'y a pas de threads disponibles, la file d'attente augmente jusqu'à ce qu'il y en ait. Il est évolutif et signifie que les clients ne sont pas bloqués même si tous les threads sont occupés - la file d'attente est la partie clé de la conception ici. –

+0

Bien qu'il semble que le système gère cela (mais pour être sûr); Ai-je besoin de concevoir/implémenter ma propre file d'attente, ou est-ce que le système va naturellement mettre en file d'attente mes opérations (tirer et oublier)? –

1

Si vous utilisez ThreadPool.QueueUserWorkItem, les éléments supplémentaires sont mis en file d'attente jusqu'à ce qu'un thread soit disponible.

3

Vous confondez les délégués avec les threads et le nombre de connexions simultanées.

Avec les liaisons bidirectionnelles WCF, la connexion reste ouverte en attendant le rappel. IIS 7 ou supérieur, sur le matériel moderne devrait avoir aucune difficulté à maintenir quelques milliers de connexions simultanées si elles sont inactives. Les délégués ne sont que des pointeurs de méthode - vous pouvez en avoir autant que vous le souhaitez. Cela ne veut pas dire qu'ils sont invoqués simultanément.

+0

Je suis en train de faire tourner les services pour tirer profit de la liaison NetTCP et avoir accès aux rappels sans compter sur la liaison DualHttp. J'appelle les délégués avec BeginInvoke depuis les méthodes WCF afin que le client et le service puissent terminer l'opération en cours le plus rapidement possible, ce qui, si je comprends bien, passe à un autre thread (le rendant ainsi multithread). À moins que je ne me trompe sur la façon dont le tout fonctionne, bien sûr. :) –

1

La quantité maximale de thread par défaut de ThreadPools est de 250 et non de 25! Vous pouvez toujours définir une limite supérieure pour le ThreadPool si vous en avez besoin.
Si votre ThreadPool manque de threads, deux choses peuvent se produire: Toutes les opperations sont mises en file d'attente jusqu'à ce que la ressource suivante soit disponible. S'il y a des threads finis, ceux-ci peuvent être "en cours d'utilisation", donc le GC va déclencher et libérer certains d'entre eux, vous fournissant de nouvelles ressources.
Toutefois, vous pouvez également créer des threads sans utiliser ThreadPool.

+0

Bien qu'à long terme, nous ayons besoin d'un grand nombre de threads et de connexions simultanés, très probablement nous n'aurons qu'un petit nombre de clients accédant à notre service central (et encore moins tous en même temps). Cependant, il faut l'adapter à cela ("juste au cas où"). –