Passer et traiter des 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 pour un jeu d’enregistrements volumineux ou complexe peut prendre du 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 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 au format 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.

Notes

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 une 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 implémentée par l’objet. 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’y a 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 de sortie 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 ne sera pas apparent au client, car le client recevra les mêmes paramètres de sortie et la même valeur de retour qu’il aurait reçu 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 impossible à distinguer, tout 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 que le client effectue. 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 :