处理异常的更干净的方法是什么
本文关键字:方法 是什么 异常 处理 | 更新日期: 2023-09-27 18:24:09
请参阅以下代码:
try
{
int val = GenericLibrary.ConvertToInt(userInput);
return "Valid number";
}
catch (Exception)
{
return "Invalid number";
}
我编写了一个控制台应用程序,它有许多try、catch块。我想以更干净的方式处理异常,并遵循DRY原则。
在控制台应用程序c#中处理错误的最佳方法是什么?
我可以使用Func或Action吗?
我可以使用面向方面编程吗?如何使用?
我想澄清一下,更干净-如果你只想在一个地方写错误处理代码,那么你可以使用AOP(例如PostSharp)。但是要意识到,通过AOP使用错误处理程序,它们将在exe中的任何位置进行编译。
还要记住,这违反了异常处理程序应在异常情况下使用的规则。
我不知道为什么要在Try-Catch中将string
转换为int
。
通过设置全局异常处理程序Application.ThreadException
和AppDomain.CurrentDomain.UnhandledException
,您可以在一个位置处理意外异常。记住要处理所有期望的异常,例如字符串到int的强制转换。
您可以使用Func进行此强制转换,但使用简单的方法Integer.TryParse
会更容易。
什么是干净的取决于很多因素。通过PostSharp或其他AOP处理程序的通用异常处理程序,例如企业库中的异常处理应用程序块,甚至可以让您配置策略。尽管这是一个不错的想法,但在策略injecion应用程序块到位之前,它从未获得过太多的吸引力,这也是一个AOP框架,允许您以可配置的方式集中处理异常。
然而,在现实中,异常处理仍然很困难。第一条规则应该是永远不要隐藏异常。当然,你可以捕捉它们,但当你不让它们进一步传播时,你应该总是记录它们。如果您的GenericLibrary使用一些配置文件来决定应该在哪个区域设置中处理整数,但找不到其配置文件,该怎么办?您会得到重复的错误,但在调试之前永远不会找到根本原因,因为您丢弃了异常对象并返回了一个字符串。
一个同样糟糕的"处理"策略是对
catch(Exception ex)
{
Log("Error has occured: {0}", ex.Message);
}
这将给您错误消息,但您会丢失完整的调用堆栈和任何内部异常。如果您收到一些像TargetInvocationException这样只包含一般错误消息的一般包装器异常,这将特别糟糕。
正确的处理策略在很大程度上取决于您的具体环境。如果控制台应用程序是一个未交付给客户的小型应用程序,那么通常最简单的做法是在第一次传递中删除所有捕获处理程序,并在主方法中全局处理它们。然后,当您有处理最常见的非致命错误的经验时,您可以重新添加必要的catch处理程序以恢复健壮性。现在,您继续处理非致命错误,但对致命错误保留故障快速策略。
这里之前的任何答案都只会给你使用这个或那个策略的建议,但你需要根据具体情况决定哪些例外对你的应用程序来说不是关键的。当你捕捉到所有内容时,你不会发现为什么你的应用程序因为内部捕捉到的错误而什么都没做。如果您根本没有处理,您的应用程序将在每个非致命错误时终止(例如,如果无法在应用程序中解析值,则可以返回0)。
对于一个小型控制台应用程序,我会
- 拆除所有挡块
- 即使在Main方法中
这样,如果您的应用程序崩溃,您就可以在应用程序事件日志中自动记录.NET Framework,而无需付出额外的努力。如果你的控制台应用程序被执行,例如作为一项计划作业,将输出打印到控制台对你没有多大帮助。这是处理异常的最干净的方法:根本不进行处理,让应用程序崩溃,这样你就可以在应用程序事件日志中找出问题所在。
如果除了部署可执行文件外,还部署了用于发布构建的pdb,那么您还可以获得行号和文件信息,这使得在大多数情况下很容易发现错误。
如果您的应用程序是关键任务型的或已交付给客户,那么您需要使用一些日志框架来登录到一些私有日志文件。控制台应用程序和窗口应用程序之间的区别只是PE标头中的一个标志。Windows应用程序将从当前启动的控制台分离,而控制台应用程序将保持连接。这是唯一的区别。您也可以在控制台应用程序中创建WPF应用程序,但只要控制台运行,它就会阻止您的控制台,这可能不是您想要的。
但是,如果您切换到Windows应用程序,您可以分配一个新的控制台,使console.WriteLine能够再次工作,并且您可以继续使用printf调试,这可能是最常用的调试方法,尽管这是一种非常老式的方法。
通常,你会在应用程序中添加一个跟踪库,以跟踪默认情况下关闭的应用程序流。还应该进行日志记录,它总是打开的,只进行错误日志记录。使用这种方法,如果错误日志记录还不够的话,您可以在客户机器上选择更多的故障处理选项。
如果您想使用Func,请参阅:你可以使用这个
public static class SafeExecutor
{
public static T Execute<T>(Func<T> operation)
{
try
{
return operation();
}
catch (Exception ex)
{
// Log Exception
}
return default(T);
}
}
var data = SafeExecutor.Execute<string>(() =>
{
// do something
return "result";
});