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 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 purge
Je 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