在 C# 中创建有保证的异常安全方法
Create a guaranteed exception safe method in C#
我最近实现了一个使用 JSON.SerializeObject.
记录对象内容的功能
长话短说,我们的想法是,这个函数将用于我们新实现的日志记录机制,以根据系统参数化在需要时跟踪对象。
整个日志记录机制的一个绝对要求是它永远不应该抛出异常,因为它会被广泛使用。任何开发人员都应该能够使用它,并且在任何情况下此功能都不应导致代码流中断。如果失败,任何调用都应该被跳过。
在实现它并检查并处理了我能想到的每个异常之后,我决定将整个功能包装在一个外部 try-catch 块中,以防万一。
像这样:
public static void TrackObject(object obj)
{
try { Console.WriteLine(JsonConvert.SerializeObject(obj)); }
catch { Console.WriteLine("Failed to track object."); }
}
在出色地通过所有测试后,我启动了主应用程序以进行一些实际环境测试。
令我惊讶的是,由于 Nuget 配置错误,我的函数在调用之后但在进入 try-catch 块之前引发异常 (System.IO.FileLoadException),因此它传播回主应用程序,导致代码破坏流.
这让我开始思考。
有一些方法可以在调用函数时但在处理程序启动之前抛出异常。也有一些情况下异常是完全不可接受的。
我目前的解决方案是创建一个包装函数,它只是调用 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
Is there a way to create a bullet-proof, no-way in hell, exception free method?
没有。即使该方法实际上是空的,您始终可以抛出线程中止异常,或者如果堆栈上没有足够的 space 来调用该方法,则堆栈溢出异常,否则可能会导致内存不足异常。
is there a definitive list of exceptions that can occur on a method call?
如果它是任意代码(即来自委托)则否。它可能始终是某种类型的自定义异常,在您编写代码时甚至不存在。
另请注意,在您的情况下,如果您只想尝试处理正常异常(不同于上面提到的那些)发生在你的 try
块中。仅记录异常可能会失败。在您使用控制台的示例中,标准输出可能会出现问题,从而导致异常。如果你真的想要这个代码永远不会抛出你需要尝试记录异常,但是当它们不工作时有其他备份日志记录选项(如果你真的不能抛出,正如其他人所提到的,这几乎肯定是一个坏主意,那么如果记录异常失败,你需要愿意继续而不记录。
我最近实现了一个使用 JSON.SerializeObject.
记录对象内容的功能长话短说,我们的想法是,这个函数将用于我们新实现的日志记录机制,以根据系统参数化在需要时跟踪对象。
整个日志记录机制的一个绝对要求是它永远不应该抛出异常,因为它会被广泛使用。任何开发人员都应该能够使用它,并且在任何情况下此功能都不应导致代码流中断。如果失败,任何调用都应该被跳过。
在实现它并检查并处理了我能想到的每个异常之后,我决定将整个功能包装在一个外部 try-catch 块中,以防万一。
像这样:
public static void TrackObject(object obj)
{
try { Console.WriteLine(JsonConvert.SerializeObject(obj)); }
catch { Console.WriteLine("Failed to track object."); }
}
在出色地通过所有测试后,我启动了主应用程序以进行一些实际环境测试。 令我惊讶的是,由于 Nuget 配置错误,我的函数在调用之后但在进入 try-catch 块之前引发异常 (System.IO.FileLoadException),因此它传播回主应用程序,导致代码破坏流.
这让我开始思考。
有一些方法可以在调用函数时但在处理程序启动之前抛出异常。也有一些情况下异常是完全不可接受的。
我目前的解决方案是创建一个包装函数,它只是调用 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
Is there a way to create a bullet-proof, no-way in hell, exception free method?
没有。即使该方法实际上是空的,您始终可以抛出线程中止异常,或者如果堆栈上没有足够的 space 来调用该方法,则堆栈溢出异常,否则可能会导致内存不足异常。
is there a definitive list of exceptions that can occur on a method call?
如果它是任意代码(即来自委托)则否。它可能始终是某种类型的自定义异常,在您编写代码时甚至不存在。
另请注意,在您的情况下,如果您只想尝试处理正常异常(不同于上面提到的那些)发生在你的 try
块中。仅记录异常可能会失败。在您使用控制台的示例中,标准输出可能会出现问题,从而导致异常。如果你真的想要这个代码永远不会抛出你需要尝试记录异常,但是当它们不工作时有其他备份日志记录选项(如果你真的不能抛出,正如其他人所提到的,这几乎肯定是一个坏主意,那么如果记录异常失败,你需要愿意继续而不记录。