简体   繁体   English

我可以避免C#中的异常,继续执行代码吗?

[英]Can I avoid exceptions in C#, continuing code execution?

I have the following C# code. 我有以下C#代码。 Whenever an exception is caught, say at line 1, I am never able to reach other lines (2, 3, 4, etc). 每当发现异常时,例如在第1行,我将永远无法到达其他行(2、3、4等)。

try
{
    line1
    line2
    ...
}
catch (Exception ex)
{
    ...
}

Is it possible, in C#, to say that if line 1 generates an exception, just continue on to the other lines (2, 3, 4, etc)? 在C#中是否可以说,如果第1行生成异常,则继续其他行(2、3、4等)?

Exceptions should not be ignored. 异常不应该被忽略。 :) :)
They exists and are thrown for a reason: an exceptional situation has occured, a certain condition is not met, and I cannot continue working ... 它们的存在和抛出是有原因的:发生了特殊情况,不满足特定条件,并且我无法继续工作...

It is possible to ignore exceptions, if you put a try / catch block around each line of code, but I don't think that you really want to do that ... 如果在每行代码周围放置一个try / catch块,则可以忽略异常,但是我不认为您确实想这样做。

You could create a SkipOnError method like this: 您可以创建一个SkipOnError方法,如下所示:

private SkipOnError(Action action)
{
    try 
    {
        action();
    }
    catch
    {
    }
}

Then you could call it like so: 然后可以这样称呼它:

try
{ 
    SkipOnError(() => /*line1*/);
    line2;
    line3;
} catch {}

Edit: This should make it easier to skip a given exception: 编辑:这应该使跳过给定异常更加容易:

private SkipOnError(Action action, Type exceptionToSkip)
{
    try 
    {
        action();
    }
    catch (Exception e)
    {
        if (e.GetType() != exceptionToSkip) throw;            
    }
}

NOTE: I'm not actually suggesting you do this - at least not on a regular basis, as I find it rather hacky myself. 注意:实际上,我并不是建议您这样做-至少不是定期进行的,因为我自己觉得这很不客气。 But it does sort of show off some of the functional things we can now do in C#, yay! 但这确实展示了我们现在可以在C#中完成的一些功能性的事情,是的!

What I would really do is this: Refactor line1 into a method ( Extract Method ). 我真正要做的是:将line1重构为方法( Extract Method )。 That new method should handle any foreseeable exceptions (if they can be handled) and thus leave the caller in a known state. 该新方法应处理任何可预见的异常(如果可以处理),从而使调用者处于已知状态。 Because sometimes you really want to do line1 , except, maybe it's ok if an error happens... 因为有时候您真的想做line1 ,否则,如果发生错误也许没关系...

just put a try catch around line1 只是尝试抓住第一线

try
{
    try
    {
        line1
    }
    catch (Exception ex)
    {
       ...
    }

    line2
    ...
}
catch (Exception ex)
{
    ...
}

Frederik is right though you really need to be careful when doing this. 弗雷德里克(Frederik)是对的,尽管您在执行此操作时确实需要小心。 It should be used on a case by case basis. 应根据具体情况使用。 Only when you know that the process should continue should you use it. 仅当您知道该过程应该继续时,才应使用它。 Otherwise you should handle the exception accordingly. 否则,您应该相应地处理异常。

If there's code that you always want to be executed, even if an exception is thrown, even if the exception either doesn't get caught in the catch block, or the catch block re-throws or throws a new exception, it should go in the "finally" block: 如果您始终希望执行代码,即使引发了异常,即使该异常未在catch块中被捕获,或者catch块重新引发或引发了新的异常,也应将其放入“最终”块:

try
{
  do(something);
}
catch (InvalidArgumentException ex)
{
  onlyDealWithOneExceptionType();
}
finally
{
  always.runs(no, matter, what);
}

You can isolate each line into a try-catch block, however that just wreaks of codesmell to me. 您可以将每一行隔离为一个try-catch块,但是那只是代码的混乱。 If you are certain that the lines after line one do not throw exceptions, or need to be executed regardless of the exception and will not throw additional errors, you can add a finally block after the first catch. 如果确定第一行之后的行不会引发异常,或者无论异常如何都需要执行并且不会引发其他错误,则可以在第一个catch之后添加一个finally块。 Example: 例:

try{
  line 1;
}
catch(Exception exc){
  //Error handling logic here
}
finally{
  line 2;
  line 3;
  .
  .
  .
  line n;
}

您可以只将第1行包装在try catch块中。

You can always do 你总是可以做

try 
{
   line1
}
catch (Exception ex)
{
}
line2
...

But there is nothing like a 'retry' keyword. 但是没有什么比“重试”关键字更重要的了。

As suggested, you should wrap the try catch around line1 in this particular example. 如建议的那样,在此特定示例中,应将try catch换行。 However, for future note you should only really ever have conditions in your try catch block that you only want to be completed IF there are no exceptions. 但是,为了以后的注意,您应该只在try catch块中真正有条件,只有在没有例外的情况下才想完成。

You can put the other lines in a finally clause, but that would be quite ugly, especially if these can throw exceptions as well... 您可以将其他行放在finally子句中,但这将非常难看,尤其是如果这些行也可能引发异常的话...

You should recover from the first exception, and then carry on to the next line, wrapping each in a try/catch statement. 您应该从第一个异常中恢复过来,然后继续进行下一行,将每条异常包装在try / catch语句中。

As others have said, ensure first that "ignoring" the exception is what you really want to do. 正如其他人所说,首先要确保“忽略”异常是您真正想要做的。 If it still is, and the syntactic overhead of all the try-catch's is too high, you could wrap it up with the execute-around idom. 如果仍然存在,并且所有try-catch的语法开销都很高,则可以将其与iexec环绕起来。

I don't have time to sketch out all the code right now - but what you'd do is write a method that takes an anonymous delegate and executes it within a try-catch (maybe logging any exceptions, or filtering ones that are "ok"). 我现在没有时间草绘所有代码-但是您要做的是编写一个方法,该方法采用一个匿名委托并在try-catch中执行它(也许记录任何异常,或过滤那些“好”)。 Call this method something like tryDo. 调用此方法类似于tryDo。 You could then write you code something like this: 然后,您可以编写如下代码:

tryDo( delegate(){ line1; } );
tryDo( delegate(){ line2; } );

It's still a little verbose, but then you don't want to make this stuff too easy. 仍然有些冗长,但是您不想让这些事情变得太简单了。 It's just enough overhead to make you keep wondering if it's the right thing to do :-) 足够的开销让您不断怀疑这是否是正确的事情:-)

You will need reifiable continuations to do that. 您将需要可更改的继续执行此操作。 The CLR and C# does not support that, and will probably never do so. CLR和C#不支持该功能,并且可能永远不会支持。 :( :(

try
{
    line1
    line2
    ...
}
catch (Exception ex)
{
    ...
}
finally
{
    if(line1ErrorOccured)
    {
        line2
        ...
    }
}

not given it too much thought though 虽然没有考虑太多

If it's possible to handle your exception and continue, you should localize your try/catch blocks. 如果可以处理异常并继续,则应本地化try / catch块。

try
{
  line1;
}
catch (ExpectedException e)
{
  // Handle your exception, prepare data for the next lines
  // Could you have prevented the exception in the first place?
}

try
{
  line2;
  line3;
}
catch (AnotherExpectedException e)
{
  // Maybe this exception you can't continue from. Perhaps log it and throw;
}

Remember that exceptions are exceptional. 请记住,例外是例外。 If an exception is thrown, something should have gone wrong. 如果引发异常,则应该有问题。 You should try to prevent the exceptions in the first place. 您首先应该尝试防止异常。

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

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