【问题标题】:Exit the function/method if an exception occurs如果发生异常,退出函数/方法
【发布时间】:2019-02-12 21:15:24
【问题描述】:

如果子方法中发生异常,我正在尝试找到退出整个方法的代码。我尝试在 Subfunction() 的 catch 部分添加 return 但该过程将继续到 Thirdfunction()

 public static void Mainfunction()
    {
        try
        {
            //some code
            //some code
            Subfunction();
            ThirdFunction();

        }
        catch(Exception ex)
        {
            //write to log
        }
    }

    public static void Subfunction()
    {
        try
        {
            //some code
            //some code

        }
        catch (Exception ex)
        {
            //write to log
        }
    }

因此,基本上,如果 Subfuntion() 中发生错误,我想从 Mainfunction() 停止进程,而不继续执行 ThirdFunction()。任何帮助将不胜感激。谢谢

【问题讨论】:

  • 从子函数中移除 try/catch
  • 如果这很简单并且您必须在子函数中捕获,您可以重新抛出(只需在捕获块中使用 throw;)。但让它冒泡更有效。
  • 基本上,是的。除非你让 SubFunction 返回一个值,然后你检查那个值。
  • 唯一有意义的。为什么你甚至需要在SubFunction 中捕获?如果答案是“仅用于记录”,您可以(并且显然已经)通过MainFunction 中的捕获来实现这一点。
  • 见我的第二条评论。您也可以将其包装在您的自定义异常中并抛出它。但再次......这是有争议的。

标签: c# asp.net exception


【解决方案1】:

基本上有两组可能的解决方案:使用异常和不使用。

使用例外,我建议让它冒泡,正如我在 cmets 中已经说过的那样。

然后你可以重新抛出:

try {
   // exception here
}
catch(Exception ex)
{
   throw;
   // Attention: this is _different_ from "throw ex" !!
}

注意这里:

您还可以在 catch 块中使用 throw e 语法来实例化您传递给调用者的新异常。 在这种情况下,原始异常的堆栈跟踪(可从 StackTrace 属性获得)不会保留

throw (C# Reference)(我强调)

我自己是从 Java 过来的,这是像我这样的人在从 Java 过渡到 .Net 时会遇到的问题。因此,如果您的团队中有新的“java 人”:不要对他们苛刻,只需将他们指向文档即可。

你可以换行:

try {
   // exception here
}
catch(Exception inner)
{
   throw new MyCustomException( "Some custom message", inner);
}

顺便说一句:捕获异常通常不是一个好主意。大多数时候,您希望捕获您可以实际处理的特定异常。


另一类解决方案是没有冒泡异常:

返回值:

public static bool Subfunction()
{
    bool success = true;

    try
    {
        //some code
        //some code

    }
    catch (Exception ex)
    {
        // TODO write error log!
        success = false;
    }
    return success;
}

或者带有返回码或错误码:

// DO NOT USE MAGIC NUMBERS !
private static readonly int SUCCESS_INDICATOR = 0;
private static readonly int ERROR_INDICATOR = 1;

// TODO DOCUMENT which errorcodes can be expected and what they mean!
public static int Subfunction()
{
    int success = SUCCESS_INDICATOR;

    try
    {
        //some code
        //some code

    }
    catch (Exception ex)
    {
        // TODO write error log!
        success = ERROR_INDICATOR;
    }
    return success;
}

尤其是团队中有“C-Guys”时,您可能会偶然发现这个。 (无意冒犯 - 只是我的经验)

或者使用状态对象...

public static void Mainfunction()
{
    try
    {
        //some code
        //some code
        ISuccessIndicator success = new ISIImplementation();
        Subfunction( success );
        if( !succes.HasException ) 
        {
            ThirdFunction();
        }
        else
        {
            // handle exception from Subfunction
        }

    }
    catch(Exception ex)
    {
        //write to log
        //Exceptions from ThrirdFunction or "else" branch are caught here.
    }
}


public static void Subfunction( ISuccessIndicator result )
{
    try
    {
        //some code
        //some code

    }
    catch (Exception ex)
    {
        result.HasException=true;
        result.Exception = ex;
    }
}


public interface ISuccessIndicator 
{
    Exception Exception {get; set;}
    bool HasException {get; set;}
}

如果你真的疯了,你可以......

public static void Mainfunction()
{
    try
    {
        //some code
        //some code
        Exception ex = null;
        Subfunction( ref ex );
        if( ex == null ) // or more modern: ( ex is null )
        {
            ThirdFunction();
        }
        else
        {
            // handle exception from Subfunction
        }
    }
    catch(Exception ex)
    {
        //write to log
        //Exceptions from ThirdFunction or "else" branch caught here.
    }
}


public static void Subfunction( ref Exception outEx )
{
    try
    {
        //some code
        //some code

    }
    catch (Exception ex)
    {
        outEx = ex;
    }
}

请注意,我绝不会鼓励使用后者。但这是可能的 ...并且 OP 要求提供可能性。

免责声明:所有 sn-ps 未经测试。谁发现错误可以保留它们(但请写评论,以便我修复它们)。

【讨论】:

  • 在调用不稳定的第三方 DLL 时,通用 catch 非常有用。
  • @JulieC 正如我所写,如果可以,请捕获您可以处理的特定异常。现在你的观点是“古怪的第三方库”。诚然,如果您没有记录在案的 API 并且您真的不知道实际会抛出哪些异常,那么您可能至少想要记录它们而不管它们的类型。但是您需要了解,您需要区分这是否使您处于一致状态并适当地处理它。
【解决方案2】:

如果 Subfuntion() 中发生错误,我想停止该过程 来自 Mainfunction()

在你的方法Subfunction中删除try/catch的最简单方法

如果你想在这个方法中保留try/catch,(用于日志记录什么的),重新抛出异常

    public static void Main()
    {
        try
        {           
            Subfunction();
            Thirdfunction();
        }
        catch(Exception ex)
        {
        }
    }    
    public static void Subfunction()
    {
        try
        {
            throw new AccessViolationException();
        }
        catch (Exception ex)
        {
            throw;
        }
    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-06-05
    • 1970-01-01
    • 2022-08-17
    • 2011-05-29
    • 1970-01-01
    • 2012-12-13
    • 2022-01-20
    • 2017-10-23
    相关资源
    最近更新 更多