C#在try catch的catch块中使用Continue

14
现在,我在 continue 语句方面遇到了一个严重的问题。FetchUnseenMessages 可能会根据它是否能够连接到指定的电子邮件帐户返回错误。如果 FetchUnseenMessages 失败,我希望 continue 语句返回到 foreach 语句中的下一项(尝试下一个电子邮件帐户)。但我得到了一些意外的结果。我不认为 continue 语句会跳转到 foreach 语句中的下一项,而是回到 try 语句的开头并再次尝试。我已经被卡住了一整天,感到非常困扰。请帮忙看一下,谢谢,Chris。
foreach (string l in lUserName)
{ 
    try
    {
        newMessages = FetchUnseenMessages(sUsername);
    }
    catch
    {
        continue;
    }

    //Other code
}

3
这样吞噬所有异常是非常糟糕的做法。相反,只吞没你期望被抛出的那种类型的异常。catch (某些异常类型) { } - Igby Largeman
3
你的方法没有传入变量l。那你为什么认为正在运行错误的循环呢? - Aron
1
我不相信continue语句会跳到foreach语句的下一项。你怎么知道的?你的代码甚至没有使用l - Sergey Kalinichenko
为了解决这个问题,我已经删除了很多代码。FetchUnseenMessages函数传递了变量username 4次(所有不同的用户名),但现在它只循环了4次,而且只传递了相同的第一个用户名(4次)。所以,我猜问题是foreach语句正在循环,但没有跳到下一个值。 - DigitalRayne
1个回答

30
你可以在 catch 块中使用一个名为 flag 的 bool 变量,并在 catch 块执行后,如果 flag 表示执行了 catch 块,则执行 continue 语句。
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 
}

如果 continue 语句退出一个或多个带有关联 finally 块的 try 块,控制权最初将转移到最内层 try 语句的 finally 块。当控制权到达 finally 块的结束点时,控制权将转移到下一个封闭 try 语句的 finally 块。这个过程重复进行,直到所有介于 try 语句的 finally 块都被执行,msdn
根据给定的细节,continue 的行为应该是正常的,你不应该有任何问题。你可能有其他问题,比如 closure variable in a loop,你可以在 这里 阅读更多关于变量闭包的内容。
我已经进行了测试来验证给定的场景,看起来是正常的。
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");
    }
}

使用 catch 中的 continue 输出
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

循环变量封闭
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());
}

循环封闭变量的输出
9
9
9

循环变量封闭的解决方案,复制循环变量并将其传递给操作。

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

输出

0
1
4

4
你应该提到,foreach 循环的闭包语义(而不是其他循环,比如 forwhile)从 C# 4 变为 C# 5。因此,如果您在某个匿名函数(通常是 lambda 表达式,带有 => 箭头)中捕获了由 foreach 声明的变量,则结果取决于您使用的 C# 版本。 - Jeppe Stig Nielsen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接