【问题标题】:How handle an exception in a loop and keep iterating?如何处理循环中的异常并保持迭代?
【发布时间】:2010-10-08 12:46:16
【问题描述】:

我需要一个 for 循环,即使任何一次迭代中出现任何异常,它也能完成所有迭代。

【问题讨论】:

  • 这听起来像是一个旧鞋与玻璃瓶的问题:tinyurl.com/shoevbottle。您可能需要提供更多详细信息以获得更好的解决方案,包括您尚未考虑的想法。
  • Wedge,我同意...如果您必须将 try/catch 放入 for 循环中,如下所示,那么解决方案可能有问题。
  • @Wedge:很好的比喻,我的另一个书签,谢谢

标签: c# for-loop


【解决方案1】:

您知道异常是什么以及会导致什么吗?你能测试它并防止它被抛出,即。 CanCompleteStep 或 TryCompleteStep。如果您无法完成,请跳过该步骤。然后,您可以将异常处理置于循环之外。

【讨论】:

    【解决方案2】:

    循环没有内置功能可以做到这一点。这不是 C# 中内置的语言功能,它不会自动处理异常并继续循环。

    此外,请尽量避免将 try-catch 块放入循环中。即使它解决了您提到的问题,请考虑编译器和运行时必须做那么多额外的工作。如果没有异常发生,那一切都会白费。

    相反,让例外成为例外。这是异常发生的事情:在您设计的输入考虑之外。当然,这只是一个建议,如果你真的要继续循环,请使用上面建议的两个选项。

    【讨论】:

    • 没有内置功能?比如说,CATCH 怎么样?
    • 做或不做。没有尝试。 ,-)
    • 我给了你一个 +1。因为我想我理解您想要指出的,如果在“迭代”期间发生异常并且您捕获它,则“迭代”本身就是“损坏”。因此,您可以保证在所有情况下“操作”都已完成。 (很难用语言来形容……)
    • @TomTom - 谢谢。这就是我的意思。为了更清楚,我正在编辑:(
    • 如果没有抛出异常,try-catch 没有性能开销。 msmvps.com/blogs/peterritchie/archive/2007/06/22/…
    【解决方案3】:

    我认为还值得注意的是,如果您使用的是通用列表 - 您可以使用以下内容来迭代集合:

    ForEach(动作动作)

    http://msdn.microsoft.com/en-us/library/bwabdf9z.aspx

        EmployeesList.ForEach(ProcessEmployee);
    
        void ProcessEmployee(Employee employeeItem)
        {
            try
            {
                ...
            }
            catch { }
        }
    

    这有利于使循环中的代码可重用。

    【讨论】:

      【解决方案4】:

      或者,如果这是您的程序中反复出现的模式,并且您正在为这种捕获所有异常样式承担风险,请将其包装为您的集合的扩展。将其应用于前面的示例:

      people.ForEachIgnorant(ofThrowingWorkOnPerson);
      

      或者:

      people.ForEachIgnorant(p => WorkOnPersonThatThrows(p));
      

      实施:

      public static void IgnorantForEach<T>(this IEnumerable<T> source, Action<T> action)
      {
          foreach (var item in source)
          {
              try
              {
                  action(item);
              }
              catch { }
          }
      }
      

      【讨论】:

      • 更好的是,添加 Action&lt;Exception&gt; 类型的参数并在 catch 块中调用它。这样,调用者可以确定它是如何处理的,而您不会吞下异常。
      【解决方案5】:

      问题是……您的解决方案必须包含一个 for 循环和某种错误/异常处理过程,因此您可能必须在您的 for 循环中嵌入一个 try catch 语句。

      如果引发异常,您将无法像未引发异常时那样完成一次迭代。但是,通过使用 try catch,您可以确保您的循环执行所有不引发异常的迭代。

      如果您在 for 循环中嵌入异常处理方面需要帮助,请使用 teedyay 发布的示例!

      【讨论】:

        【解决方案6】:
        for (...)
        {
            try
            {
                // Do stuff
            }
            catch (Exception ex)
            {
                // Handle (or ignore) the exception
            }
        }
        

        【讨论】:

        • 性能提示,将您的声明放在 for 循环之外。
        • @freggel:哈哈,和我想给的小费一样。但这是最好的解决方案。
        • 提示:请使用定义更严格的异常然后异常说ApplicationException。捕获异常的一个大问题是 ThreadAbortException 会在此处捕获,您真的要阻止应用程序在此处停止吗?捕获 OutOfMemoryException 怎么样?
        • ThreadAbortExceptions 的行为与其他异常不同,所以这不会成为问题:msdn.microsoft.com/en-us/library/… 但是,我同意最好尽可能具体地捕捉到什么。
        • 完全没有资格!异常必须与队列一起收集,并且在循环结束时,检查队列收集的任何异常,如果有一些异常必须构建 AggregateException 并抛出它们。 msdn.microsoft.com/en-us/library/system.aggregateexception.aspx
        【解决方案7】:

        只需将每次迭代放在 try..catch 中

        foreach(Person a in people)
        {
              try
              {
                      WorkOnPerson(a);
              }
              catch
              {
                      // do something if you want to.
               }
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2019-09-05
          • 1970-01-01
          • 1970-01-01
          • 2021-04-19
          • 1970-01-01
          • 2013-11-03
          • 1970-01-01
          相关资源
          最近更新 更多