C#try catch finally只有在未处理异常的情况下才运行代码

时间:2016-11-30 16:32:10

标签: c# exception-handling try-catch-finally

我的C#帮助程序库中有以下函数,用于更新第三方应用程序(CATIA V5)中的对象:

    public void Update(INFITF.AnyObject objectToUpdate)
    {
        try
        {
            Part.UpdateObject(objectToUpdate);
        }
        catch
        {
            throw new InvalidOperationException("Update Failed");
        }
        finally
        {
            Part.Inactivate(objectToUpdate);
        }
    }

Part.UpdateObject()有时会失败,这是不可避免的。

如果失败,我想通知函数用户更新失败,让他们有机会以自定义方式修复问题并处理异常,或以默认,稳定的方式处理异常。

我知道我发布的代码不起作用,因为如果未处理异常,finally块甚至不会被调用...但希望代码块能够实现这个想法。

更新:

我没有充分解释我的情景,所以让我澄清一下。我正在写这个函数,其他人会在开发时使用它。其中一些程序员知道如何使用try / catch块,有些则不知道。以下是可以调用函数的两个示例场景。

一个。用户熟悉try / catch块,并了解更新调用可能失败的原因。

try
{
    Update(objectToUpdate);
}
catch (InvalidOperationException ex)
{
    //fix the problem with the object to update
    //I have handled the exception, so I DO NOT want the object to be inactivated
}

B中。用户不熟悉try / catch块或者不知道更新可能失败

Update(objectToUpdate)

在这种情况下,我们希望以一种对新手程序员有意义的稳定方式处理失败的更新,并防止应用程序崩溃。 (在这种情况下,停用第三方CAD软件中的违规对象)

2 个答案:

答案 0 :(得分:0)

未处理的异常是未经处理的异常"通过调用例程,即它不被代码的任何部分捕获。在您的情况下,除了可能以某种方式与硬件,驱动程序,设备或内存相关的异常外,所有异常都被捕获,在这种情况下,应用程序将由OS终止。你可以做的不多。 您可以尝试创建AppDomain UnhandledException处理程序以尝试获取有关应用程序关闭的一些信息,但如果操作系统终止您的应用程序,这可能并不总是有效。

答案 1 :(得分:0)

讨论很有帮助,尤其是旗帜的想法。也就是说,需要从调用代码中操作标志,所以这是我的解决方案:

首先我创建了一个HandledException类:

[Serializable()]
public class HandledException : Exception
{
    public bool Handled { get; set; }

    public HandledException(string Message)
        : base(Message)
    {

    }
}

然后我将Update方法更改为如下:

[DebuggerHidden]
public void Update(INFITF.AnyObject objectToUpdate)
{
    HandledException ex = new HandledException("Update Failed");
    bool updateSuccesful = false;
    try
    {
        Part.UpdateObject(objectToUpdate);
        updateSuccesful = true;
    }
    catch
    {
        throw ex;
    }
    finally
    {
        if (!updateSuccesful && !ex.Handled)
        {
            if(!Part.IsUpToDate(objectToUpdate))
                Part.Inactivate(objectToUpdate);
        }
    }
}

这只会在更新失败时尝试取消激活CAD对象,并允许调用代码处理异常并防止对象失活。

如果用户未处理失败的更新,则会以稳定的方式处理问题。

样本用法:

try
{
    partDoc.Update(pad);
}
catch (HandledException ex)
{
    //I want the pad to be deactivated so I continue with the default behavior
    //in some scenarios I would fix the pad and mark the exception handled
    ex.Handled = false;
    string currentName = currentBody.get_Name();
    currentBody.set_Name(currentName + "_PadError");
}

感谢您的讨论,有时您只需要讨论一个问题:)