Différence entre NetworkStream.Read() et NetworkStream.BeginRead()?
J'ai besoin de lire de NetworkStream
qui permettrait d'envoyer des données au hasard et la taille des paquets de données de garder aussi divers. Je me suis mise en œuvre d'une application multi-thread où chaque thread a son propre flux de la lecture. Si il n'y a pas de données sur le flux, la demande devrait continuer à attendre pour les données arrivent. Cependant, si le serveur d'envoi de données et a mis fin à la session, il doit la quitter.
Au début, j'avais utilisé la Read
méthode pour obtenir les données à partir du flux, mais il sert à bloquer le thread et attendre jusqu'à ce que les données apparus sur le flux.
La documentation MSDN suggère,
Si aucune donnée n'est disponible pour la lecture,
la méthode Read retourne 0. Si l'
hôte distant arrête la connexion,
et l'ensemble des données disponibles a été
reçu, la méthode de Lecture complète
immédiatement et de retourner zéro octets.
Mais dans mon cas, je n'ai jamais eu le Read
méthode retourne 0 et se terminer normalement. Il attends indéfiniment.
Dans mon enquête, je suis tombé sur BeginRead
qui regarde le stream et invoque une méthode de rappel de manière asynchrone, dès qu'il reçoit les données. J'ai essayé de regarder pour les différentes implémentations à l'aide de cette approche, cependant, j'ai été incapable d'identifier quand à l'aide de BeginRead
être bénéfique, par opposition à Read
.
Que je la regarde, BeginRead
a juste l'avantage d'avoir l'appel asynchrone, ce qui ne serait pas bloquer le thread courant. Mais dans mon application, j'ai déjà un thread séparé pour lire et traiter les données de flux, de sorte que ne ferait pas beaucoup de différence pour moi.
-
Quelqu'un peut s'il vous plaît aidez-moi à comprendre l'Attente et le mécanisme de Sortie pour
BeginRead
et comment est-il différent deRead
? -
Quelle serait la meilleure façon de mettre en œuvre les fonctionnalités souhaitées?
Read
ne pas revenir. Votre approche contraire semble être la bonne direction.Eh bien, honnêtement, je ne peux pas dire que pour vous. Son un service tiers, que nous lisons. Elles ont précisé que la fermeture horaires et nous supposons que cela se passe comme mentionné. Je veux juste vérifier et revérifier à mon extrémité avant de soulever un drapeau.
OriginalL'auteur Danish Khan | 2010-12-08
Vous devez vous connecter pour publier un commentaire.
- Je utiliser
BeginRead
, mais continuer à bloquer le thread à l'aide d'unWaitHandle
:Fondamentalement, il permet un délai d'attente de la async lit à l'aide de la
WaitHandle
et vous donne une valeur booléenne (completed
) si la lecture a été achevé dans les délais (2000
dans ce cas).Voici mon flux de lecture de code copié et collé à partir d'un de mes Fenêtres projets Mobiles:
Si je ne me trompe pas, vous devez toujours faire appel à EndABC sur chaque BeginABC appel. Dans le code ci-dessus, si il y a un délai d'attente, la Fin n'est jamais appelé. Un rappel que les appels à la Fin (et gère toutes les exceptions possibles) devrait probablement être ajouté au code ci-dessus.
Je pense que vous vous trompez. Je l'appelle toujours une fin: int bytesRead = stream.EndRead(asyncReader); mais peut-être que je devrais changer le code pour appeler ce code directement après la ligne bool terminé = poignée.WaitOne(2000, false); afin de supprimer les doublons.
OriginalL'auteur GenericTypeTea
D'e/S asynchrone peut être utilisé pour obtenir la même quantité d'I/O en moins de threads.
Comme vous le notez, dès à présent votre application a un thread par Flux. C'est OK avec un petit nombre de connexions, mais que faire si vous avez besoin de soutien, de 10000 à la fois? Avec des e/S asynchrone, ce n'est plus nécessaire parce que la lecture de l'achèvement de rappel permet de contexte pour être passé à l'identification des flux. Votre lit n'a plus de bloc, de sorte que vous n'avez pas besoin d'un thread par Flux.
Si vous utilisez la synchronisation ou d'e/S asynchrone, il y a un moyen pour détecter et gérer le flux de quitter pertinentes sur les API des codes de retour. BeginRead doit échouer avec IOException si le support a déjà été fermé. Un arrêt complet pendant que votre async lire est en attente de déclencher un rappel, et
EndRead
vous dira alors à l'état de jouer.OriginalL'auteur Steve Townsend
Avez-vous essayez de serveur.ReceiveTimeout? Vous pouvez définir le temps de Lire() due vais attendre pour les données entrantes, avant de revenir à zéro. Dans votre cas, cette propriété est probablement infinie quelque part.
OriginalL'auteur Огњен Шобајић
BeginRead est asynchrone, ce qui signifie que votre thread principal va commencer à exécuter le Lire dans un autre processus. Alors maintenant, nous avons 2 processus parallèles. si tu veux obtenir le résultat, u appeler EndRead, qui donne le résultat.
certains psudo
mais si votre thread principal n'a rien d'autre à faire et u ont besoin de la suite, u devrait appeler à Lire.
Steve, je pense que @ Bonshington signifiait "Thread", quand il a dit "Processus".
OriginalL'auteur Bonshington