C#try.catch-将错误处理流从一个捕获重定向到下一个捕获

本文关键字:一个 重定向 下一个 错误 catch- 处理 C#try | 更新日期: 2023-09-27 17:57:44

我试了一下。。捕获块,看起来像这样:

try
{
    ...
}
catch (IOException ioEx)
{
    ...
}
catch (Exception ex)
{
    ... 
}

我只想处理某种类型的IOException,即共享冲突(Win32 0x20)。其他IOExceptions和所有其他Exception子代通常应由第二个catch-all catch处理。

一旦我知道IOException不是共享冲突,我如何将错误处理流干净地重定向到通用catch?如果我在catch (IOException)中重新抛出,则第二个catch不会调用。我知道我可以试试。。捕获,但有更干净的方法吗?

EDIT:关于分解处理程序逻辑

在方法中分解重复代码肯定会起作用,但我注意到,通常情况下,当您使用分解方法处理异常时,它往往会出现微妙的问题。

首先,catch子句可以直接访问异常之前的所有局部变量。但是,当你将异常处理"外包"给另一个方法时,你必须将状态传递给它。当你更改代码时,处理程序方法的签名也会更改,这在更复杂的场景中可能是一个可维护性问题。

另一个问题是程序流可能会被模糊。例如,如果处理程序方法最终重新抛出异常,那么C#编译器和像Resharper这样的代码分析器就看不到它:

    private void Foo()
    {
        string a = null;
        try
        {
            a = Path.GetDirectoryName(a);
            System.Diagnostics.Debug.Print(a);
        }
        catch (Exception ex)
        {                
            HandleException(ex, a); //Note that we have to pass the "a"
            System.Diagnostics.Debug.Print(
                "We never get here and it's not obvious" + 
                "until you read and understand HandleException"
            );
            ...!
        }
    }
    static void HandleException(Exception ex, string a)
    {
        if (a != null)
            System.Diagnostics.Debug.Print("[a] was not null");
        throw (ex); //Rethrow so that the application-level handler catches and logs it
    }

    private void Bar()
    {
        string a = null;
        try
        {
            a = System.IO.Path.GetDirectoryName(a);
            System.Diagnostics.Debug.Print(a);
        }
        catch (Exception ex)
        {                
            if (a != null)
                System.Diagnostics.Debug.Print("[a] was not null");
            throw; //Rethrow so that the application-level handler catches and logs it
            System.Diagnostics.Debug.Print(
                "We never get here also, but now " + 
                "it's obvious and the compiler complains"
            );
            ...!
        }
    }

如果我想避免这些(小)问题,那么似乎没有比嵌套更干净的方法了。。正如汉克指出的那样。

C#try.catch-将错误处理流从一个捕获重定向到下一个捕获

只需将处理逻辑分解为一个单独的方法。

try
{
    ...
}
catch (IOException ioEx)
{
    if (sharing violation)
       HandleSharingViolation();
    else 
       HandleNonsharingViolation();
}
catch (Exception ex)
{
       HandleNonsharingViolation();
}

或者自己测试异常

catch (Exception ex)
{
     if (ex is IOException && ex.IsSharingViolation()
       HandleSharingViolation();
     else
       HandleNonsharingViolation();
}

不,您必须嵌套。

一旦你进入了其中一个catch块,这个"try"就被认为是已处理的。

我认为这可能很有道理,"共享违规"听起来像是一个特例,可能不像你想象的那样与其他情况紧密相连。如果使用nest-try-catch,特殊情况下的try块是否必须围绕完全相同的代码?当然,它也可以作为一个单独的方法进行重构。

创建处理异常的方法,将异常传递给该方法,基于类型以您想要的方式处理异常。在这两个块中调用这些方法。

使用嵌套的try-catch块。

try
{
    try
    {
    }
    catch (IOException ioEx)
    {
        if (....)
        else
           throw;
    }
}
catch
{
}

"finally"怎么样?

一旦您知道IOException不是共享冲突,就可以首先在IOException块中设置一个"变量"。然后,在你的finally块中,如果设置了"变量",你就可以继续做你需要做的任何事情。

以下impl。经过测试和确认

        bool booleanValue = false;
        try
        {
            test1(); // this would thro IOException
        }
        catch (IOException e)
        {
            booleanValue = true; // whatever you need to do next
        }
        finally
        {
            if (booleanValue)
            {
                Console.WriteLine("Here");
            }
        }

试用此嵌套块

尝试

}

catch(异常ioex)

尝试

}
catch(异常ex)

}
}