2017-10-17 6 views
2

De this answer et Docs, il est indiqué que pour l'accès au flux concurrent, la lecture et l'écriture peuvent être effectuées sans problème s'il y a UN thread unique pour la lecture et UN thread unique pour l'écriture.Accès simultané du flux réseau sur la même machine

Je vais avoir la configuration suivante, également montré dans l'image ci-dessous:

J'ai 2 services distincts Tester Service et My Service. Chacun d'eux a un Server et un Client. Chacun des serveurs et clients a 2 tâches WriterTask et ReaderTask.

Le problème auquel je suis confronté est qu'après un certain temps, le client donne IOException 10060. En fait, le serveur de l'autre côté fonctionne bien.

Maintenant, la documentation indique un thread unique pour l'opération de lecture/écriture, y a-t-il un problème si c'est sur la même machine?

Quelqu'un d'autre faisait face à une situation similaire auparavant?

enter image description here

Reader serveur:

private void ReaderTask(NetworkStream stream) 
    { 
     while (true) 
     { 
      // Some code 
      try 
      { 
       if (stream.CanRead) 
       { 
        var readTask = Task.Run(() => 
        { 
         MyObj message = null; 
         try 
         { 
          message = Deserialize<MyObj>(stream); 
          Console.WriteLine("ReaderTask: Read"); 
          // Some code 
         } 
         catch (IOException e) 
         { 
          Console.WriteLine("ReaderTask: " + e.Message); 
         } 
         return message; 
        }); 
        while(!readTask.Wait(1000)) 
        { 
         Console.WriteLine("ReaderTask: Wait 1000"); 
        } 
        if (readTask.Result != null) 
        { 
         Console.WriteLine("ReaderTask: Message received" + readTask.Result.toString()); 
        } 
       } 
      } 
      catch (IOException e) 
      { 
       Console.WriteLine("ReaderTask: " + e.Message); 
      } 
     } 
    } 

client Writer:

private void WriterTask(NetworkStream stream) 
    { 
     while (true) 
     { 
      // Some code 
      try 
      { 
       if (stream.CanWrite) 
       { 
        // message = getMessage(); 
        Serialize(stream, message); 
        Console.WriteLine("WriterTask: Write"); 
        // Some code 
       } 
      } 
      catch (IOException e) 
      { 
       Console.WriteLine("WriterTask: " + e.Message); 
      } 
      Thread.Sleep(1000); 
     } 
    } 
+0

Oui, j'ai fait face à une situation similaire et le problème était dans mon code, pas lié à la séparation entre les threads de lecture et d'écriture. Comment savez-vous que "le serveur fonctionne bien"? Y a-t-il un thread qui bloque actuellement l'opération 'NetworkStream.Read()' du client qui plante? –

+0

@ C.Evenhuis "le serveur fonctionne bien" - les tâches de lecture et de lecture du serveur généraient des journaux. Et donc je savais qu'ils allaient bien. Mais la tâche de lecture du serveur lisait le flux dans une tâche asynchrone qui bloquait indéfiniment. J'ai mis des informations détaillées dans ma réponse ci-dessous. Si vous avez plus d'informations, ce serait bien si vous postez une réponse et remplissez plus de détails. –

Répondre

1

je me suis dit ce que le problème.

Je ne recevais pas de données de mon serveur car, je n'ai pas défini un délai d'attente de réception sur le client comme ceci client.ReceiveTimeout = 2000. Pour cette raison, le serveur aurait ReaderTask bloqué sur l'appel en lecture.

Je ne suis pas sûr à 100% de savoir pourquoi lorsque le WriterTask du client écrirait dans le flux, le ReaderTask du serveur ne lirait rien et resterait bloqué. Mais une fois que j'ai mis un délai sur l'objet client dans le serveur, tout a commencé à fonctionner normalement.

Donc, y a-t-il un problème si les applications avec ReaderTask et WriterTask uniques sont sur la même machine? Lorsque vous utilisez un délai d'attente de réception, aucun problème. Sans délai de réception, cela n'a pas fonctionné normalement (du moins dans mon cas).

+0

Si le client envoie des données, l'opération 'Read()' du serveur ne bloquera plus - à partir de votre description, il semble que le client n'envoie rien parce qu'il attend des données. Mais c'est difficile à dire sans code. Vous ne devriez pas avoir à régler 'ReceiveTimeout' pour résoudre ce problème. –

+0

@ C.Evenhuis Sans le timeout de réception, après quelques lectures et écritures, tout d'un coup le lecteur de serveurs boucle indéfiniment dans 'while (! ReadTask.Wait (1000))' alors que la tâche est bloquée à 'message = Deserialize (flux);Même si l'auteur du client a écrit sur le flux - que j'ai vérifié à partir des journaux. Maintenant, cependant, je ne sais pas pourquoi cela arrivait. Voir ma question pour le code pertinent. –