在C#中创建一个保证的异常安全方法

时间:2018-03-22 15:10:52

标签: c# exception exception-handling

我最近实现了一个使用JSON.SerializeObject记录对象内容的函数。

简而言之,我们的想法是,这个函数将用于我们新实现的日志记录机制,根据系统参数化在需要时跟踪对象。

整个日志记录机制的一个绝对要求是,它应该永远不会抛出异常,因为它会被广泛使用。任何开发人员都应该能够使用它,在任何情况下都不应该导致代码流中断。如果失败,应该简单地跳过任何调用。

在实现它并检查并处理了我能想到的每个异常之后,我决定将整个功能包装在一个外部的try-catch块中,以防万一。

像这样:

public static void TrackObject(object obj)
{
   try { Console.WriteLine(JsonConvert.SerializeObject(obj)); }
   catch { Console.WriteLine("Failed to track object."); }
}

在通过所有测试后,我启动了主应用程序以进行一些实际的环境测试。 令我惊讶的是,由于Nuget配置错误,我的函数在调用之后引发了异常(System.IO.FileLoadException),但在它进入try-catch块之前因此传播回主应用程序,导致代码破坏流动。

这让我思考。

在调用函数时但在处理程序启动之前,有一些方法可以抛出异常。还有一些情况下异常是不可接受的。

我目前的解决方案是创建一个包装函数,它只是调用try-catch中的实际函数。但这看起来很丑陋和错误。此外,我不确定它是一种防弹解决方案。

public static void TrackObject(object obj)
{
   try { PrivateTrackObject(obj); }
   catch { Console.WriteLine("Failed to track object."); }
}

private static void PrivateTrackObject(object obj)
{
   Console.WriteLine(JsonConvert.SerializeObject(obj));
}

有没有办法在地狱中创建一个防弹,无法免费的方法?

或者至少是否有方法调用可能发生的明确的例外列表?

PS。编译器警告我版本不匹配,但我没有第一次看到它。

PS2。我为希望看到这个问题的人创建了一个示例项目。 https://drive.google.com/open?id=15BDrLNn87gsMHc9pQ-TgyDMSLQxDBq18

1 个答案:

答案 0 :(得分:2)

  

有没有办法在地狱中创建一个防弹,无法免费的方法?

没有。即使该方法实际上是空的,也可以始终抛出线程中止异常,或者如果堆栈上没有足够的空间来调用该方法,则堆栈溢出异常,或者它可能导致内存不足异常。

  

是否存在可在方法调用中发生的明确的异常列表?

如果它是任意代码(即来自代表),那么没有。它可能始终是某种类型的自定义异常,在您编写代码时甚至不存在。

另请注意,在您的情况下,如果您只是想尝试处理正常异常(与上面提到的异常不同),您需要关注可能会在catch块中抛出任何可能的异常发生在您的try区块中。只记录异常可能会失败。在使用控制台的示例中,标准输出可能会出现导致异常的问题。如果你真的想要这个代码永远不会抛出你需要尝试记录异常,但是当它们不工作时还有其他备份记录选项(和如果你真的不能抛出,正如其他人所提到的,几乎肯定是一个坏主意,那么如果记录你的异常失败,你需要愿意继续而不记录。)