web-dev-qa-db-ja.com

C#でwhileループをエスケープする方法

Whileループから脱出しようとしています。基本的に、「if」条件が満たされた場合、このループを終了できます。

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 >>
                }
            }
        }
    }
}
56
James

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;
}

2番目のループもエスケープする場合は、フラグを使用して、outループのガードをチェックインする必要があります。

        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ガードに追加する方法を見つける必要があります。

69
Dirk

breakまたはgoto

while ( true ) {
  if ( conditional ) {
    break;
  }
  if ( other conditional ) {
    goto EndWhile;
  }
}
EndWhile:
9
zellio
6
Tim

追加のロジックを使用して続行する必要がある場合...

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;
                        }
                    }
                }
            }
        }
4
Alban

どのループを終了しようとしていますか?単純なbreak;は、内側のループを終了します。外側のループには、内側のループを中断する直前にtrueに設定される外側のループスコープ変数(ブール値exit = false;など)を使用できます。内側のループブロックの後、exitの値を確認し、trueの場合はbreak;を再度使用します。

2
tomfumb

「break」は、「最も近い」ループから抜け出すコマンドです。

Breakには多くの適切な用途がありますが、必要がない場合は使用しないでください。gotoを使用するもう1つの方法と見なすことができますが、これは悪いと考えられています。

たとえば、なぜそうではないのか:

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
}
1
Jeremy

Necro-addで申し訳ありませんが、既存の回答に欠けているものを本当に挿入したかったです(私のような人が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
}
0
Kevin