Как избежать цикла while в C # - PullRequest
56 голосов
/ 16 июля 2011

Я пытаюсь вырваться из цикла while.В принципе, если условие «если» выполнено, я хотел бы иметь возможность выйти из этого цикла:

private void CheckLog()
{
    while (true)
    {
        Thread.Sleep(5000);
        if (!System.IO.File.Exists("Command.bat"))
            continue;

        using (System.IO.StreamReader sr = System.IO.File.OpenText("Command.bat"))
        {
            string s = "";
            while ((s = sr.ReadLine()) != null)
            {
                if (s.Contains("mp4:production/CATCHUP/"))
                {
                    RemoveEXELog();

                    Process p = new Process();
                    p.StartInfo.WorkingDirectory = "dump";
                    p.StartInfo.FileName = "test.exe";
                    p.StartInfo.Arguments = s;
                    p.Start();

                    << Escape here - if the "if" condition is met, escape the loop here >>
                }
            }
        }
    }
}

Ответы [ 7 ]

68 голосов
/ 16 июля 2011

Используйте break; для выхода из первого цикла:

if (s.Contains("mp4:production/CATCHUP/"))
{
   RemoveEXELog();
   Process p = new Process();
   p.StartInfo.WorkingDirectory = "dump";
   p.StartInfo.FileName = "test.exe"; 
   p.StartInfo.Arguments = s; 
   p.Start();
   break;
}

Если вы хотите также выйти из второго цикла, вам может потребоваться использовать флаг и включить защиту выходного цикла:

        boolean breakFlag = false;
        while (!breakFlag)
        {
            Thread.Sleep(5000);
            if (!System.IO.File.Exists("Command.bat")) continue;
            using (System.IO.StreamReader sr = System.IO.File.OpenText("Command.bat"))
            {
                string s = "";
                while ((s = sr.ReadLine()) != null)
                {
                    if (s.Contains("mp4:production/CATCHUP/"))
                    {

                        RemoveEXELog();

                        Process p = new Process();
                        p.StartInfo.WorkingDirectory = "dump";
                        p.StartInfo.FileName = "test.exe"; 
                        p.StartInfo.Arguments = s; 
                        p.Start();

                        breakFlag = true;
                        break;
                    }
                }
            }

Или, если вы хотите просто полностью выйти из функции из вложенного цикла, введите return; вместо break;.

Но на самом деле это не лучшие практики.Вы должны найти способ добавить необходимую логическую логику в свои while охранники.

9 голосов
/ 16 июля 2011

break или goto

while ( true ) {
  if ( conditional ) {
    break;
  }
  if ( other conditional ) {
    goto EndWhile;
  }
}
EndWhile:
6 голосов
/ 17 июля 2011
4 голосов
/ 16 июля 2011

Если вам нужно продолжить с дополнительной логикой, используйте ...

break;

или если у вас есть значение для возврата ...

return my_value_to_be_returned;

Однако, глядя на ваш кодЯ полагаю, что вы будете управлять циклом с помощью приведенного ниже примера без использования разрыва или возврата ...

private void CheckLog()
        {
            bool continueLoop = true;
            while (continueLoop)
            {
                Thread.Sleep(5000);
                if (!System.IO.File.Exists("Command.bat")) continue;
                using (System.IO.StreamReader sr = System.IO.File.OpenText("Command.bat"))
                {
                    string s = "";
                    while (continueLoop && (s = sr.ReadLine()) != null)
                    {
                        if (s.Contains("mp4:production/CATCHUP/"))
                        {
                            RemoveEXELog();

                            Process p = new Process();
                            p.StartInfo.WorkingDirectory = "dump";
                            p.StartInfo.FileName = "test.exe"; 
                            p.StartInfo.Arguments = s; 
                            p.Start();
                            continueLoop = false;
                        }
                    }
                }
            }
        }
2 голосов
/ 16 июля 2011

Из какого цикла вы пытаетесь выйти? Простой break; выйдет из внутреннего цикла. Для внешнего цикла вы можете использовать внешнюю переменную области цикла (например, boolean exit = false;), которая устанавливается в значение true перед тем, как разорвать внутренний цикл. После блока внутреннего цикла проверьте значение выхода и, если оно истинно, снова используйте break;.

1 голос
/ 16 июля 2011

«break» - это команда, которая выходит из «ближайшего» цикла.

Хотя есть много хороших вариантов использования для перерыва, вы не должны использовать его, если вам не нужно - это можно рассматривать как еще один способ использовать goto, который считается плохим.

Например, почему бы и нет:

while (!(the condition you're using to break))
        {
         //Your code here.
        }

Если причина, по которой вы используете «break», заключается в том, что вы не хотите продолжать выполнение этой итерации цикла, вы можете использовать ключевое слово «continue», которое сразу же переходит к следующей итерации цикла. цикл, будь то время или для.

while (!condition) {
   //Some code
   if (condition) continue;
   //More code that will be skipped over if the condition was true
}
0 голосов
/ 15 сентября 2016

Извините за некро-добавление, но я действительно хотел вставить кое-что, чего не хватает в существующих ответах (для любого, как я, наткнувшегося на этот вопрос через Google): рефакторинг вашего кода. Это не только облегчит чтение / ведение, но и полностью устранит такие проблемы управления маршрутизацией.

Вот к чему бы я стремился, если бы мне пришлось запрограммировать указанную выше функцию:

private const string CatchupLineToIndicateLogDump = "mp4:production/CATCHUP/";
private const string BatchFileLocation = "Command.bat";

private void CheckLog()
{
    while (true)
    {
        Thread.Sleep(5000);
        if (System.IO.File.Exists(BatchFileLocation))
        {
            if (doesFileContainStr(BatchFileLocation, CatchupLineToIndicateLogDump))
            {
                RemoveLogAndDump();
                return;
            }
        }
    }
}

private bool doesFileContainStr(string FileLoc, string StrToCheckFor)
{
  // ... code for checking the existing of a string within a file
  // (and returning back whether the string was found.)
}

private void RemoveLogAndDump()
{
  // ... your code to call RemoveEXELog and kick off test.exe
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...