async attendent d'utilisation avec TcpClient
J'ai récemment commencé à utiliser le nouveau C#5.0 "async" et "en attente" de mots clés. J'ai pensé que j'ai eu le twist, mais s'est rendu compte d'une chose qui m'a fait douter. Voici comment j'étais en mode asynchrone de la réception de données à partir d'une distance TcpClient. Une fois que j'accepte la connexion j'appelle cette fonction :
static async void ReadAsync(TcpClient client)
{
NetworkStream ns = client.GetStream();
MemoryStream ms = new MemoryStream();
byte[] buffer = new byte[1024];
while(client.Connected)
{
int bytesRead = await ns.ReadAsync(buffer, 0, buffer.Length);
ms.Write(buffer, 0, bytesRead);
if (!ns.DataAvailable)
{
HandleMessage(ms.ToArray());
ms.Seek(0, SeekOrigin.Begin);
}
}
}
Après réception des données, la boucle va juste sur et sur sans lire quoi que ce soit. J'ai testé avec une Console.WriteLine dans la boucle. Suis-je l'utiliser correctement? Je sens que je ne devrais pas être en utilisant une boucle while...
Donc, vous avez écrit des données dans un
Pourquoi êtes-vous de vérifier
Je me sens comme j'ai été poster ce que beaucoup ces derniers temps, mais utilisez Uniquement
êtes-vous sûr de
non, j'ai dit que le appelant pouvez l'utiliser pour décider si lire la synchronisation ou asynchrone. Si elle est non nulle, on peut raisonnablement utiliser une synchronisation de lire et de s'attendre à un retour rapide. Si elle est égale à zéro, nous devons passer à async. Il n'y a pas beaucoup d'autres utilisations de celui-ci, et la plupart du temps, je vois des gens de toucher
MemoryStream
, vous appelez HandleMessage
maintes et maintes fois sur la même MemoryStream
jusqu'à ce que plus de données sont disponibles. Qu'attendez-vous d'arriver?Pourquoi êtes-vous de vérifier
DataAvailable
ici? Que a rien à faire avec les messages etc. L'utilisation principale en est que, en décidant de lire de synchronisation ou asynchrone. Vous aussi ne sont pas toujours purger le back-buffer - vous rewind, mais vous n'avez pas de purgeJe me sens comme j'ai été poster ce que beaucoup ces derniers temps, mais utilisez Uniquement
async void
pour les gestionnaires d'événements. Méthodes asynchrones qui ne renvoient rien doit être async Task
. Il ya un tas de raisons, sans doute le plus important, c'est que les exceptions non gérées peuvent provoquer de très mauvais, un comportement inattendu.êtes-vous sûr de
DataAvaliable
? Selon MSDN: Use the DataAvailable property to determine if data is ready to be read. If DataAvailable is true, a call to Read returns immediately.
non, j'ai dit que le appelant pouvez l'utiliser pour décider si lire la synchronisation ou asynchrone. Si elle est non nulle, on peut raisonnablement utiliser une synchronisation de lire et de s'attendre à un retour rapide. Si elle est égale à zéro, nous devons passer à async. Il n'y a pas beaucoup d'autres utilisations de celui-ci, et la plupart du temps, je vois des gens de toucher
DataAvailable
, ils sont de l'utiliser de façon inappropriée (pour essayer de détecter la fin d'un message / image - qui est pas ce que cela signifie)
OriginalL'auteur Philippe Paré | 2014-06-08
Vous devez vous connecter pour publier un commentaire.
La
TcpClient.Connected
valeur n'est pas mise à jour immédiatement. Selon MSDN:Afin d'avoir
TcpClient.Connected
comme une boucle while condition n'est pas un bon choix.TcpClient.DataAvailable
est utilisé pour les opérations synchrones et ne sont pas utilisés pour asynchrones.Mise à jour de votre code:
Quand
ReadAsync
retour 0, cela signifie que la connexion TCP à la clôture ou fermé. Dans MSDN:OriginalL'auteur comphilip
J'ai fini par utiliser la longueur de préfixe de messages, de préfixer chaque paquet de 4 octets représentant la longueur des données à venir.
OriginalL'auteur Philippe Paré