简体   繁体   English

c#如何捕获异常并恢复执行

[英]c# how to catch exception and resume execution

Good day! 美好的一天!

i write simple console program. 我写简单的控制台程序。 It have func Main () and class Adapter; 它有func Main()和类Adapter;

some simple code that explains how it works: 一些简单的代码解释了它的工作原理:

void Main()
{
    try
    {
        Work(array);
        //subcribing at some events;
        Application.Run();  
    }
    catch(Exception ex)
    {
        //write to log;
    }
}
class Adapter
{
    ....
    public void GetSomething()
    {
        try
        {
            ...some work and exception goes here;
        }
        catch(Exception ex)
        {
            //catch exception and do Work:
            Work(array);
        }
    }
}

When exception goes- it catches at GetSomething. 当异常发生时,它会捕获GetSomething。 So,i write some values.But i need that the program still running after exception. 所以,我写了一些值。但是我需要程序在异常后仍然运行。 But after catch in GetSomething method it goes to Exception ex at Main func and program exits; 但是在GetSomething方法中捕获之后,它会转到Main func和program exits的Exception ex;

How to do that program will still running after catch exception in GetSomething method? 如何在GetSomething方法中捕获异常后仍然运行该程序? Thank you! 谢谢!

If what you want is to catch an exception and continue execution at the point of failure (which might be several layers down in the call stack) and possibly retrying the failed statement, you're pretty much out of luck. 如果你想要的是捕获一个异常并在失败点继续执行(可能是调用堆栈中的几层)并且可能重试失败的语句,那你几乎没有运气。

Once your catch clause is invoked, the stack has been unwound up to that point. 一旦调用了catch子句,堆栈就已经解开到那一点。 You can deal with the exception in some way and then choose zero or one of 您可以通过某种方式处理异常,然后选择零或一个

  • Continuing the exceptio via throw ; 通过throw ;继续throw ;
  • Re-throwing the exception via throw e; 通过throw e;重新抛出异常throw e;
  • Throwing a new exception via throw new SomeException(); throw new SomeException();抛出一个新的异常

If didn't choose one of the above, execution continues at the point following the try/catch/finally block. 如果没有选择上述之一,则在try/catch/finally块之后的点继续执行。 For example: 例如:

    try
    {
      DoSomethingThatMightThrowAnException() ;
    }
    catch ( Exception e )
    {

      DoSomethingToHandleTheExceptionHere() ;

      // Then, choose zero or one of the following:
      throw                  ; // current exception is continue with original stack trace
      throw e                ; // current exception is re-thrown with new stack trace originating here
      throw new Exception()  ; // a new exception is thrown with its stack trace originating here
      throw new Exception(e) ; // a new exception is thrown as above, with the original exception as the inner exception

    }
    finally
    {
       // regardless of whether or not an exception was thrown,
       // code in the finally block is always executed after the try
       // (and the catch block, if it was invoked)
    }

    // if you didn't throw, execution continues at this point.

If you don't do one of the above, execution continues at the statement following the try/catch/finally block. 如果您不执行上述操作之一,则会在try/catch/finally块之后的语句处继续执行。

The best you can do as far as retrying is something like this: 就重试而言,你能做的最好的事情就像这样:

// retry operation at most 3
int number_of_retries = 5 ;
for ( int i = 0 ; i < number_of_retries ; ++i )
{
  try
  {

     DoSomethingThatMightThrowAnException() ;

     break ; // exit the loop on success

  }
  catch( Exception e )
  {

     Log.Error("well...that didn't work") ;

     ExecuteRecoveryCode() ;

  }

}

This behavior is not possible in .NET. 在.NET中无法执行此行为。 When an exception is thrown, control exits the current point and continues onto the first catch statement it can find in the call stack, or exits the program, thus eliminating execution of the call stack up to that point. 抛出异常时,控制退出当前点并继续执行它可以在调用堆栈中找到的第一个catch语句,或退出程序,从而消除了到此时执行的调用堆栈。 This is part of the definition of exceptional behavior. 这是异常行为定义的一部分。

You can instead break down the process being done by Work and process each item one at a time to enable the same effect as what you're asking. 您可以改为分解由Work完成的过程并一次处理一个项目,以实现与您所要求的相同的效果。 In other words, instead of Work(array) , try 换句话说,而不是Work(array) ,尝试

foreach(var item in array)
{
    try { WorkSingle(item); }
    catch { continue; }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM