2011-11-19 5 views
5

Je dois créer un service WCF qui accepte la requête du client et se connecte en interne à un ordinateur distant pour effectuer le travail. La machine distante a une très bonne capacité de traitement mais pas une bonne vitesse de traitement. Cela signifie que vous pouvez traiter par exemple 1000 transactions par seconde, mais que chaque transaction peut prendre 1 seconde, la seule façon est d'avoir 1.000 transactions simultanées en cours dans la même seconde. La machine distante gère très bien cette situation, mais je m'inquiète pour WCF, si chaque transaction est interne (je ne m'inquiète pas du modèle côté client (sync ou async)) en attente et en bloquant un thread dans le serveur pour 1 ou 2 secondes cela pourrait représenter 1.000 threads de travail en live et cela pourrait être très dangereux, ou peut-être que WCF utilise le pool de threads et met juste les autres requêtes en attente et c'est aussi mauvais. Donc, ma question concerne la possibilité de traiter la requête de manière asynchrone côté serveur. Ainsi, le flux de transaction doit être comme ceci:Traitement côté serveur asynchrone WCF

  1. Cliente initialize une demande (dans son côté est une demande synchrone)
  2. serveur recive la demande et de mettre cette demande dans une transaction de file d'attente et libérer le fil
  3. Lorsque la tâche se termine, le serveur termine la requête en envoyant le HTTP 200 et le résultat au client.

Merci!

+0

Si vous utilisez votre service wcf dans IIS, vous n'aurez rien à faire de plus. IIS spoulera un thread séparé pour chaque requête, instanciera une nouvelle instance de votre wcf, traitera la requête et retournera les résultats. Si un thread existant est disponible, IIS l'utilisera au lieu d'en spouler un nouveau. – edepperson

+0

Cela ne résout pas mon problème de Thread "saturation", j'ai besoin d'un traitement asynchrone qui n'est pas la réutilisation de thread –

Répondre

1

Vous pouvez utiliser le modèle asynchrone WCF pour y parvenir. Lorsque vous marquez votre operationContract avec l'attribut async, WCF utilise les threads IO CompletionPort pour traiter la demande.

donc cela fonctionne de la façon suivante. Votre requête est gérée par un thread dans IIS et une fois qu'il atteint WCF, il se met en veille puis le thread IO CompletionPort prend le processus de demande, puis renvoie la réponse au thread IIS qui renvoie la réponse au client.

Les threads IO CompletionPort sont beaucoup plus rapides et ne ralentissent pas votre serveur en termes de performances ou de ressources. Pour plus d'informations, consultez le link suivant.

+0

Mais comment faire cela. Avec un paramètre simple, il n'est pas possible de libérer un thread qui attend une réponse d'une base de données o d'une machine externe. L'async doit être implémenté par le développeur, seul le développeur sait comment la transaction reprend après un événement async completed.Vous répondez AIM pour éviter le blocage de thread entre IIS et WCF mais pas entre WCF et base de données (par exemple) –

+0

Voulez-vous dire que vous ne voulez pas qu'un thread soit bloqué du tout jusqu'à ce que le processus soit terminé. Dans un tel scénario, vous pouvez soit prendre l'option IsOneWayOperation où le client fait simplement une demande et oublie. Si vous souhaitez que le client récupère une réponse, essayez d'implémenter le scénario de duplex intégral dans lequel le client spécifie un rappel au serveur et une fois le traitement effectué, le serveur effectue un rappel pour mettre à jour le statut. – Rajesh

+1

J'ai trouvé que peut-être la classe de tâche async/await usign peut être la solution, je vais étudier cela. –

0

Dans le serveur de niveau intermédiaire, déclarer et mettre en œuvre votre opération selon le modèle async:

[OperationContract(Action = "DoSomething", AsyncPattern = true)] 
IAsyncResult BeginDoSomething(AsyncCallback asyncCallback, object asyncState); 
void EndDoSomething(IAsyncResult iar); 

La mise en œuvre de BeginDoSomething doit envoyer la demande à la machine distante et revenir immédiatement. Lorsque vous appelez DoSomething() côté client, WCF du niveau intermédiaire réalise que cette opération est implémentée en tant que paire début/fin asynchrone et l'appelle de manière appropriée.

Questions connexes