14

Now, I'm having a major problem with the continue statement. FetchUnseenMessages may or may not return an error depending on whether or not it's able to connect to a specified Email account. I want the continue statement to go back up to the next item in the foreach statement (trying the next email account) should FetchUnseenMessages fail. I'm getting some unexpected results. I don't believe the continue statement is going to the next item in the foreach statement but going back to the beginning of the try statement and trying it again. I've been stuck on this all day and I'm pretty stuck. Please help. Thanks, Chris.

foreach (string l in lUserName)
{ 
    try
    {
        newMessages = FetchUnseenMessages(sUsername);
    }
    catch
    {
        continue;
    }

    //Other code
}
DigitalRayne
  • 389
  • 2
  • 3
  • 14
  • 3
    Swallowing all exceptions like this is a Very Bad practice. Instead, only swallow the type of exception you expect to be thrown. `catch (SomeExceptionType) { }` – Igby Largeman Feb 26 '14 at 04:41
  • 3
    l isn't being passed into your method. So what makes you think the wrong loop is being run,? – Aron Feb 26 '14 at 04:41
  • 1
    "I don't believe the continue statement is going to the next item in the foreach statement" How do you know? Your code doesn't even use `l`. – Sergey Kalinichenko Feb 26 '14 at 04:41
  • I've taken a lot of the code out for the purpose of this problem. FetchUnseenMessages is passed the variable username 4 times (all different user names) and right now it's looping 4 times but only the same first username is being passed (4 times). So, I guess the problem is that the foreach statement is looping but not jumping to the next value. – DigitalRayne Feb 26 '14 at 04:54

1 Answers1

30

You can use a bool variable flag set in catch block and execute continue statement after catch if flag indicates the execution of catch block.

foreach (string l in lUserName)
{ 
   bool isError = false;  //flag would remain flase if no exception occurs 
   try
   {
       newMessages = FetchUnseenMessages();
   }
   catch
   {
       isError = true;
   }
   if(isError) continue;   //flag would be true if exception occurs
   //Other code 
}

If the continue statement exits one or more try blocks with associated finally blocks, control is initially transferred to the finally block of the innermost try statement. When and if control reaches the end point of a finally block, control is transferred to the finally block of the next enclosing try statement. This process is repeated until the finally blocks of all intervening try statements have been executed, msdn.

Edit By the given details the behaviour of the continue should be normal not you should not have any problems. You might have some other problem like closure variable in a loop, you can read more about variable closure here.

I have made a test to verify the given scenario and it appears to be normal.

for (int i = 0; i < 3; i++)
{
    try
    {
    Console.WriteLine("Outer loop start");
    foreach (int l in new int[] {1,2,3})
    {       
        Console.WriteLine("Inner loop start");
        try
        {
            Console.WriteLine(l);
             throw new Exception("e");
        }
        catch
        {
            Console.WriteLine("In inner catch about to continue");
            continue;
        }           
        Console.WriteLine("Inner loop ends after catch");

    }
    Console.WriteLine("Outer loop end");
    }
    catch
    {
        Console.WriteLine("In outer catch");
    }
}

The output using continue in catch

Outer loop start
Inner loop start
1
In inner catch about to continue
Inner loop start
2
In inner catch about to continue
Inner loop start
3
In inner catch about to continue
Outer loop end
Outer loop start
Inner loop start
1
In inner catch about to continue
Inner loop start
2
In inner catch about to continue
Inner loop start
3
In inner catch about to continue
Outer loop end
Outer loop start
Inner loop start
1
In inner catch about to continue
Inner loop start
2
In inner catch about to continue
Inner loop start
3
In inner catch about to continue
Outer loop end

Loop variable enclosure

List<Func<int>> actions = new List<Func<int>>();
int variable = 0;
while (variable < 3)
{
    actions.Add(() => variable * variable);
    ++ variable;
}

foreach (var act in actions)
{
    Console.WriteLine(act.Invoke());
}

Output of loop enclosure variable

9
9
9

Solution of loop variable enclosure, make a copy of loop variable and pass it to action.

while (variable < 3)
{
    int copy = variable;
    actions.Add(() => copy * copy );
    ++ variable;
}

Output

0
1
4
Community
  • 1
  • 1
Adil
  • 146,340
  • 25
  • 209
  • 204
  • 4
    You should mention that the closure semantics of `foreach` loops (not other loops like `for` or `while`) changed from C# 4 to C# 5. So if you do capture the variable declared by `foreach` inside some anonymous function (typically a lambda expression, with the `=>` arrow), the result depends on your C# version. – Jeppe Stig Nielsen Feb 26 '14 at 11:27