2009-06-05 8 views
2

J'essaie de programmer un serveur client basé sur l'infrastructure de rappel fournie par WCF, mais il ne fonctionne pas de manière asynchrone.WCF: le rappel n'est pas asynchrone

Mon client se connecte au serveur appelant une méthode de connexion, où je sauve le client canal de rappel en faisant

MyCallback callback = 
     OperationContext.Current.GetCallbackChannel<MyNamespace.MyCallback>() 

Après que le serveur exécute une partie et utilise l'objet de rappel pour communiquer avec le client. Tout cela fonctionne, le problème réside sur le fait que même si j'ai défini la méthode dans le OperationContract comme IsOneWay=true, le serveur se bloque toujours lors de l'appel au client. J'ai testé cela en lançant le serveur pour le débogage dans Visual Studio, en le détachant, en lançant le client, en appelant la méthode de connexion mentionnée ci-dessus, en mettant un point d'arrêt dans la méthode de rappel implémentée du client et en rendant le le serveur envoie une réponse au client. Le serveur arrête de faire ce qu'il est censé faire, en attendant la réponse du client.

Toute aide est appréciée.

Répondre

0

Je pense que la solution à votre problème est de définir correctement les attributs 'ConcurecyMode' et 'Instance ContextMode' pour votre service. Pour ce faire, vous devez décorer votre déclaration de service avec ces attributs comme indiqué dans le ci-dessous exemple:

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Reentrant)] 
    public class SubscriberService: ISubscriberServiceContract 
{...} 

InstanceContextMode.Single builds votre service comme un objet Singleton donc il n'y a qu'une seule instance de votre service en cours d'exécution pour tous les clients;

ConcurencyMode.Reentrant ou ConcurencyMode.Multiple active le travail multithread pour l'instance de service. Pour 'Multiple', vous devez prendre en charge la synchronisation de threads dans votre service.

+0

J'ai déjà eu marqué comme multiple, et essayé avec Reentrant et c'est pareil. J'ai lu que même si un service est marqué comme unilatéral, il peut toujours bloquer dans certaines conditions, le problème est que dans mon cas, c'est la norme au lieu d'une exception. Je suppose que c'est lié à la façon dont la liaison est configurée mais je ne vois rien qui puisse le changer. Merci pour l'aide. –

+0

Multiple et réentrant ne fonctionnait pas car même si nous autorisons plusieurs threads pour le moment, il est configuré pour n'en autoriser qu'un seul. Pourtant, cela ne résout pas le problème car l'appel se bloque quand il ne devrait pas. Je vais mettre en œuvre un thread qui gère l'envoi des messages. Merci pour tout. –

0

Avez-vous essayé de mettre

[CallbackBehavior(UseSynchronizationContext = false)] 

sur l'objet côté client implémente l'interface de rappel?

1

L'astuce consiste à appeler le rappel de manière asynchrone à partir du serveur. Regardez ceci:

[OperationContract(IsOneWay = true, AsyncPattern = true)] 
    IAsyncResult BeginOnMessageReceived(LiveDataMessage message, AsyncCallback acb, object state); 
    void EndOnMessageReceived(IAsyncResult iar); 
+0

Comment est définie la méthode de fin, je ne peux que supposer est par convention 'EndOnMessageReceived' où EndOn définit l'opération de fin? Avez-vous des liens vers des exemples où cela est mis en œuvre s'il vous plaît en tant que google/SO ne soulevant aucun des hits que je peux trouver. – g18c

Questions connexes