【问题标题】:Execute multiple functions, but stop when an error occured执行多个功能,但发生错误时停止
【发布时间】:2020-06-17 21:14:45
【问题描述】:

我想一个接一个地使用多个函数,但如果第一个函数出现问题,则不应执行其他函数。目前我正在使用带开关的while循环。有没有办法用其他东西跳过整个 while/switch 部分?可能是活动之类的?

while (!ErrorActive && iStep != 3)
{
    switch (iStep)
    {
        case 0:
            DoSomething(); // this can trigger ErrorActive
            iStep = 1;
            break;

        case 1:
            DoSomething2(); // this can trigger ErrorActive
            iStep = 2;
            break;

        case 2:
            DoSomething3(); // this can trigger ErrorActive
            iStep = 3;
            break;
    }
}

DoSomething 函数有这样的东西:

public void DoSomething()
{
    try
    {
        //calculate something
    }
    catch
    {
        ErrorActive = true;
    }
}

有没有办法跳过整个 while/switch 部分并用其他东西替换它(比如可能是一个事件?)或者我应该总是在每个函数之间保留一些东西来检查一切是否正常?

【问题讨论】:

    标签: c# events while-loop switch-statement


    【解决方案1】:

    只需将渔获物上移一级:

    // true if all steps executed, false otherwise
    bool DoSteps()
    {
       int lastExecutedStep = 0;
       try{
         DoSomething();
         lastExecutedStep = 1;
         DoSomething1();
         lastExecutedStep = 2;
         DoSomething2();
         lastExecutedStep = 3;
       }
       catch( IOException ioex )
       {
          // log IO Exception
       }
       // ... catch more expected exception types
    
       return (lastExecutedStep == 3);
    }
    
    void DoSomething(){
       // NO try/catch here
    }
    

    即使没有计步器也可以:

    // true if all steps executed, false otherwise
    bool DoSteps()
    {
       try{
         DoSomething();
         DoSomething1();
         DoSomething2();
         return true;
       }
       catch( IOException ioex )
       {
          // log IO Exception
       }
       // ... catch more expected exception types
    
       return false;
    }
    

    要了解更多学术方法,您可能想探索Chain of responsibility pattern

    【讨论】:

    • 这不是很奇怪吗?例如,我正在执行一些函数来从文件中获取信息第一个函数读取文件,这可能会因 IOexception 而失败第二个函数需要将一些值从字符串转换为具有不同类型异常的 int。比我在这个 try catch 中应该有 x 个捕获量。我可以通过 catch (Exception E) 来捕获所有异常,但这不是真正的 gd?
    • 你能详细说明一下吗?你觉得这有什么奇怪的地方?
    • 当您实际从文件中创建某种对象时,奇怪的是在创建此对象时您可能会遇到 IO 异常或转换异常。这就是为什么我想反其道而行之,感觉更自然
    • 好吧,我不知道你觉得什么是“自然”的。当然,抓Exception 是万能的,不推荐。您应该忽略它并捕获特定的异常类型。请注意,创建 try/catch 上下文是昂贵的。在这里,您只有一个而不是 n。所以,这减少了开销。如果您有更多要求,则应修改问题中的示例。
    • 什么意思?它们独立的功能。如果抛出,将继续执行 catch 块。将跳过 try 块中在 throwing 之后的所有代码。
    【解决方案2】:

    你可以这样做,为什么在解决方案很简单的情况下使用这么马赫的代码。

    if(!ErrorActive){
     DoSomething(); // this can trigger ErrorActive
    }
    
    if(!ErrorActive){
     DoSomething1(); // this can trigger ErrorActive
    }
    
    if(!ErrorActive){
     DoSomething2(); // this can trigger ErrorActive
    }
    

    【讨论】:

    • 这是一种不同的方法,但我总是尽量避免 if if 语句一个接一个。我觉得看起来很可怕:)
    • 代码将逐行执行。如果您捕获到异常代码执行将跳过此 if 块
    • 我认为没有最简单的方法。不应在此上下文中使用 switch 语句
    • 或者你可以在 DoSomething() 函数体中调用 DoSomething2() 。在这种情况下你只需要一次检查和一次调用
    【解决方案3】:

    您可以将while 循环简化为for 循环,并使用新的switch 表达式语法稍微简化一下。另外,让函数返回成功状态而不是设置一些共享变量:

    void Run()
    {
        var keepRunning = true;
    
        for(int i = 0; keepRunning; i++)
        {
            keepRunning = i switch
            {
                0 => DoSomething(),
                1 => DoSomething2(),
                2 => DoSomething3(),
                _ => false
            };
        }
    }
    
    bool DoSomething()
    {
        try
        {
            return true;
        }
        catch
        {
            return false;
        }
    }
    
    bool DoSomething2()
    {
        try
        {
            return true;
        }
        catch
        {
            return false;
        }
    }
    
    bool DoSomething3()
    {
        try
        {
            return true;
        }
        catch
        {
            return false;
        }
    }
    

    【讨论】:

    • 啊哈,这对我来说是新的。但是当我使用一个已经返回其他东西的函数时,比如它返回一个对象。我也不能返回布尔值
    • @Bart - 如果你需要返回一些东西以及函数的成功,你可以返回一个元组(bool Succeeded, object Result) DoSomething()
    猜你喜欢
    • 1970-01-01
    • 2019-10-22
    • 2014-12-29
    • 1970-01-01
    • 2019-05-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多