7 votes

API asynchrone pour le streaming de données à partir d'un périphérique matériel

Je suis en train d'écrire une bibliothèque en C#, mais j'ai besoin de la rendre asynchrone. Normalement, vous exposez un ensemble de fonctions DLL, qui prennent des paramètres en entrée, et renvoient une valeur une fois terminées. Mais comment puis-je faire une fonction de bibliothèque (appelable depuis C++/Delphi/Etc) qui commence déjà à renvoyer des données en continu tout en prenant des entrées?

La seule solution que je vois maintenant est de communiquer en utilisant des sockets/tuyaux/etc, au lieu d'appels DLL.

Est-ce que quelqu'un aurait un exemple de comment faire cela avec des appels DLL normaux?

1voto

Adam Mihalcin Points 8816

Un bon modèle pour un appel de bibliothèque asynchrone simple (qui se trouve dans System.dll) est WebClient.DownloadStringAsync. Cette méthode télécharge de manière asynchrone à partir d'un Uri et déclenche l'événement DownloadStringCompleted une fois terminé.

Votre bibliothèque pourrait également fournir une méthode FooAsync, qui ne bloque pas le thread actuel mais déclenche un événement FooDataReceived chaque fois que des données arrivent dans votre bibliothèque et un événement FooCompleted lorsque le calcul se termine.

0voto

RQDQ Points 8896

Il existe quelques façons de procéder. Dans la plupart des langages, vous pouvez effectuer des appels asynchrones aux méthodes en utilisant des threads ou des répartiteurs. En général, tant que vous rendez votre fichier DLL réentrant (capable de gérer plusieurs threads en même temps), l'environnement d'appel peut se charger de la partie asynchrone.

Il est également possible d'intégrer les appels asynchrones dans votre API. Un exemple de quelque chose qui le fait est les proxys clients WCF.

0voto

Corylulu Points 1821

Microsoft a un bon article sur cette question. Si vous survolez juste EndInvoke, cela devrait également fonctionner pour vous. http://msdn.microsoft.com/fr-fr/library/2e08f6yc(v=vs.71).aspx

0voto

Eugen Rieck Points 33670
  • Comme vous voulez que l'Input et l'Output soient tous les deux asynchrones, vous aurez besoin d'un thread de travail : Si ni le thread d'entrée, ni celui prenant la sortie ne peuvent être bloqués, tous deux ne peuvent pas être dérangés pour faire le travail.

  • Vous avez déjà pensé à communiquer via des pipes, mais pourquoi utiliser un pipe et pas une structure interne ?

  • Donc vous avez cette file d'attente sans verrou sur l'entrée, une autre sur la sortie et un thread de travail

  • Le thread de travail prend l'entrée de la file d'attente d'entrée, la traite, et la place dans la file d'attente de sortie

  • Si la file d'attente d'entrée devient vide, le thread de travail n'a rien à traiter, donc il déclenche un événement "besoin de plus de données" et ensuite se bloque sur la file d'attente d'entrée devenant (partiellement) pleine

  • Si le thread de travail place quelque chose dans la file de sortie, il déclenche un événement "avoir plus de données", et si la file de sortie devient (entièrement) pleine, il se bloque sur l'espace de sortie devenant disponible

  • Votre API est non bloquante : Ni l'envoi d'entrée ni la réception de sortie ne bloquent jamais

  • Votre API est asynchrone : Des notifications (via des Events) sont données

0voto

Yahia Points 49011

Selon les commentaires du demandeur initial, l'application appelante envoie de l'audio au DLL, le DLL envoie de l'audio via une interface USB, le DLL capture de l'audio depuis l'interface du microphone et doit renvoyer l'audio capturé à l'application pendant que l'application envoie de l'audio au DLL, etc.

Sur la base de cela et du fait que l'appelant peut être écrit dans des langages assez différents, je vois quelques options pour les canaux de communication :

  • TCP/IP (en fonction des "paramètres du pare-feu du bureau", cela pourrait poser problème!)
  • Canalisation (Pipes)
  • Objets COM avec des événements/gestionnaires d'événements
  • DLL avec rappel bien que cela soit un peu difficile à faire fonctionner pour tous les langages)
  • Mémoire partagée avec mutex globaux (peut faciliter la tâche pour l'application consommatrice en offrant une fonction "setup" à partir du DLL qui retourne les pointeurs et les noms de mutex)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X