2016-06-21 2 views
1

J'ai une boucle while qui commence quand j'appuie sur un bouton. Je l'utilise pour maintenir la communication avec un service sur un autre ordinateur. Le problème est que lorsque je reçois le message "Terminé" de l'autre ordinateur, j'en ai besoin pour sortir de la boucle while et arrêter d'écouter jusqu'à ce que le bouton soit à nouveau enfoncé. Rien de ce que je fais ne semble sortir de la boucle.Comment puis-je sortir de cette boucle while particulière?

Veuillez noter que tout le processus est exécuté dans son propre thread.

J'ai essayé de mettre pause; juste avant la fin du premier cas dans le commutateur, pas de chance et je ne suis pas sûr si c'est parce que c'est une déclaration de commutateur qui attend une pause; entre les cas ou quelle est la raison. J'ai également essayé de mettre retour; là mais il ne va pas encore sortir. Je finis par devoir fermer l'application et redémarrer pour utiliser le bouton à nouveau.

TcpClient client = new TcpClient(serverIP, 11000); 
NetworkStream stream = client.GetStream(); 
Byte[] bytes = new Byte[256]; 
String data = null; 
int i; 

stream.Write(copy, 0, copy.Length); 


while ((i = stream.Read(bytes, 0, bytes.Length)) != 0) 
{ 
    data = System.Text.Encoding.ASCII.GetString(bytes, 0, i); 
    //MessageBox.Show(data); 
    switch (data) 
    { 
     case "Completed": 
      this.Invoke((MethodInvoker)delegate 
      { 
       progressBar1.Value = 0; 
       progressBar1.Visible = false; 
       progressBar1.Update(); 
       if (prod) 
       { 
        sqlLink.setProdFile(imageName, destFileName); 
       } else 
       { 
        sqlLink.setTestFile(imageName, destFileName); 
        if (sqlLink.getTestVM(imageName) != "") 
        { 
         if (message.Text("Test VM", "Power on specified Virtual Machine in private mode?", MessageBoxButtons.OKCancel) == DialogResult.OK) 
         { 
          PS ps = new PS(); 
          ps.powerOnVM(sqlLink.getTestVM(imageName)); 
         } 
        } 
       } 
       //Tried putting break; here.        
      }); 
      break; 
     case "FIU": 
      { 
       progressBar1.Value = 0; 
       progressBar1.Visible = false; 
       progressBar1.Update(); 
       message.Text("Error", "The image is in use. Try shutting down machines or unassigning devices.", MessageBoxButtons.OK); 
      } 
      break; 
     case "DSF": 
      { 
       progressBar1.Value = 0; 
       progressBar1.Visible = false; 
       progressBar1.Update(); 
       message.Text("Error", "Drive space is full on production volume. Try deleting some older images.", MessageBoxButtons.OK); 
      } 
      break; 
     default: 
      this.Invoke((MethodInvoker)delegate 
      { 
       progressBar1.Value = Int16.Parse(data); 
       progressBar1.Update(); 
      }); 
      break; 
    } 
} 
    stream.Close(); //This never happens. 
    client.Close(); 
} 
catch (Exception ex) 
{ 
    message.Text("Error", "Copy Method Error: " + ex.Message, MessageBoxButtons.OK); 
} 
+0

Chaque 'case' dans le commutateur doit avoir une' briser; 'à la fin. Vous aurez besoin de sortir de la boucle while après que le cas soit touché. – pay

+0

Le problème est que je veux seulement sortir si le cas est "terminé". –

+0

Probablement juste faire ce que mon pote a dit, mettre un 'bool' et faire' if (someBool) {break; } 'en tant que première ligne après la déclaration' while' – pay

Répondre

5

Définissez une variable booléenne qui contiendra le fait que vous avez reçu le message "Terminé".

Lorsque vous entrerez dans la prochaine itération, si cette valeur est true, alors vous vous casserez et vous sortirez de votre boucle.

Exemple:


// Abbreviated 
while ((i = stream.Read(bytes, 0, bytes.Length)) != 0) 
{ 
    data = System.Text.Encoding.ASCII.GetString(bytes, 0, i); 
    bool breakTheWhile = false; 
    switch (data) 
    { 
     case "Completed": 
      // Abbreviated 
      breakTheWhile = true; 
      break; 
     case "FIU": 
      // Abbreviated 
      break; 
     case "DSF": 
      // Abbreviated 
      break; 
     default: 
      // Abbreviated 
      break; 
    } 
    if (breakTheWhile) break; 
} 
 
+0

Cela ne fonctionnera pas correctement, car vous cassez l'itération suivante, ce qui signifie que vous allez essayer de relire. Mettez la pause sous l'instruction switch – SynerCoder

+0

Dépendez de ce qui se cache derrière le flux, mais sans le savoir, vous avez raison, mieux vaut prévenir que guérir. – Sidewinder94

+0

Jusqu'à présent, cela ne fonctionne pas, je ne sais pas pourquoi. Je mets une boîte de message pour m'indiquer si ce bloc de code conditionnel basé sur isFinished que vous avez ajouté est réellement exécuté mais pas, c'est bien que isFinished soit mis à true après qu'il soit terminé comme vous l'avez fait plus haut. –