Exécution et traitement d’appels asynchrones

Les objets COM peuvent prendre en charge l’appel asynchrone. Lorsqu’un client effectue un appel asynchrone, le contrôle revient immédiatement au client. Pendant que le serveur traite l’appel, le client est libre d’effectuer d’autres tâches. Lorsque le client ne peut plus continuer sans les résultats de l’appel, il peut obtenir les résultats de l’appel à ce moment-là.

Par exemple, une demande d’un jeu d’enregistrements volumineux ou complexe peut prendre beaucoup de temps. Un client peut demander le jeu d’enregistrements par un appel asynchrone, puis effectuer d’autres tâches. Lorsque le jeu d’enregistrements est disponible, le client peut l’obtenir rapidement sans le bloquer.

Les clients n’effectuent pas d’appels asynchrones directement sur l’objet serveur. Au lieu de cela, ils obtiennent un objet d’appel qui implémente une version asynchrone d’une interface synchrone sur l’objet serveur. L’interface asynchrone sur l’objet d’appel a un nom de la forme AsyncInterfaceName. Par exemple, si un objet serveur implémente une interface synchrone nommée IMyInterface, un objet d’appel implémente une interface asynchrone nommée AsyncIMyInterface.

Remarque

La prise en charge asynchrone n’est pas disponible pour IDispatch ou pour les interfaces qui héritent d’IDispatch.

 

Les objets serveur qui prennent en charge les appels asynchrones implémentent l’interface ICallFactory . Cette interface expose une méthode unique , CreateCall, qui crée une instance d’un objet d’appel spécifié. Les clients peuvent interroger ICallFactory pour déterminer si un objet prend en charge l’appel asynchrone.

Pour chaque méthode sur une interface synchrone, l’interface asynchrone correspondante implémente deux méthodes. Ces méthodes attachent les préfixes Begin_ et Finish_ au nom de la méthode synchrone. Par exemple, si une interface nommée ISimpleStream a une méthode Read, l’interface AsyncISimpleStream aura un Begin_Read et une méthode Finish_Read. Pour commencer un appel asynchrone, le client appelle la méthode Begin_.

Lorsque vous implémentez un objet serveur, vous n’avez pas besoin de fournir un objet d’appel pour chaque interface que l’objet implémente. Si l’objet serveur implémente l’interface ICallFactory et utilise le marshaling standard, un client marshalé peut toujours obtenir un objet d’appel proxy, même s’il n’existe aucun objet d’appel côté serveur. Ce proxy marshale la méthode Begin_ en tant qu’appel synchrone, le serveur traite l’appel de manière synchrone et le client peut obtenir les paramètres sortants en appelant la méthode Finish_.

À l’inverse, si un client effectue un appel synchrone marshalé sur une interface pour laquelle il existe un objet d’appel côté serveur, le serveur traite toujours l’appel de manière asynchrone. Ce comportement n’est pas apparent au client, car le client reçoit les mêmes paramètres sortants et la même valeur de retour qu’il aurait reçue de la méthode synchrone.

Dans les deux cas, l’interaction entre le client et le serveur est marshalée comme si l’appel était synchrone : la sortie des proxys synchrones et asynchrones est indissistable, comme la sortie des stubs correspondants. Ce comportement simplifie considérablement le modèle de programmation des clients et des serveurs. Si un objet serveur implémente ICallFactory, un client marshalé n’a pas besoin de tenter de créer un objet d’appel qui n’est peut-être pas disponible — pour le client, un objet d’appel est toujours disponible.

Lorsque le client et le serveur se trouvent dans le même appartement, l’objet serveur traite l’appel effectué par le client. Si un objet d’appel n’est pas disponible, le client doit obtenir explicitement l’interface synchrone et effectuer un appel synchrone.

Pour plus d'informations, voir les rubriques suivantes :