0

请参阅此代码:

 try
    {
        int val = GenericLibrary.ConvertToInt(userInput);
        return "Valid number";
    }
    catch (Exception)
    {
        return "Invalid number";
    }

我编写了一个控制台应用程序,它有很多trycatch 块。我想以更干净的方式处理异常并遵循 DRY 原则。

在控制台应用程序 c# 中处理错误的最佳方法是什么?

我可以使用 Func 或 Action 吗?

我可以使用面向方面的编程吗?如何使用?

4

3 回答 3

4

我想澄清一下,清楚- 如果您只想在一个地方编写错误处理代码,那么您可以使用 AOP(例如 PostSharp)。但是通过 AOP 使用错误处理程序实现它们然后将在您的 exe 中的任何地方编译。

还要记住,这违反了异常处理程序应该被异常使用的规则。

我不确定你为什么在 Try-Catch 中将string演员表包裹起来。int

您可以通过设置全局异常处理程序Application.ThreadExceptionAppDomain.CurrentDomain.UnhandledException. 请记住处理您期望的所有异常,例如将字符串转换为 int 类型。

您可以使用 Func 进行此转换,但使用简单的方法会更容易:Integer.TryParse.

于 2013-07-21T05:06:02.213 回答
3

什么是干净的确实取决于很多因素。通过 PostSharp 或其他 AOP 处理程序(例如企业库中的异常处理应用程序块)的通用异常处理程序甚至可以让您配置策略。尽管这是一个不错的想法,但在策略注入应用程序块到位之前它从未获得太多关注,这也是一个 AOP 框架,它允许您以可配置的方式集中处理异常。

然而实际上异常处理仍然很困难。第一条规则应该是永远不要隐藏异常。您当然可以捕获它们,但是当您不让它们进一步传播时,您应该始终记录它们。如果您的 GenericLibrary 使用一些配置文件来决定应该在哪个语言环境中处理整数并且找不到它的配置文件怎么办?您会重复出现错误,但在调试之前您永远不会找出根本原因,因为您丢弃了异常对象并返回一个字符串。

一个同样糟糕的“处理”策略是

catch(Exception ex)
{
   Log("Error has occured: {0}", ex.Message);
}

这会给您错误消息,但您会丢失完整的调用堆栈和任何内部异常。如果您收到一些通用包装器异常,例如仅包含通用错误消息的 TargetInvocationException,这尤其糟糕。

正确的处理策略很大程度上取决于您的具体情况。如果您的意思是控制台应用程序是一个不交付给客户的小型应用程序,那么通常最简单的方法是在第一遍中删除所有捕获处理程序并在主方法中全局处理它们。然后,当您对最常见的非致命错误有经验时,您可以重新添加必要的 catch 处理程序以恢复稳健性。现在您继续处理非致命错误,但您为致命错误保留故障快速策略。

此处的任何先前答案都只会为您提供使用这种或那种策略的建议,但您需要根据具体情况确定哪些异常对您的应用程序不重要。当您捕获所有内容时,您不会发现为什么您的应用程序由于内部捕获的错误而什么也没做。如果您根本没有处理,您的应用程序将在每个非致命错误时终止(例如,如果无法在您的应用程序中解析该值,则可以返回 0)。

对于一个小型控制台应用程序,我会

  • 移除所有捕获块
  • 即使在 Main 方法中

这样,如果您的应用程序确实崩溃,您无需额外的努力就可以在应用程序事件日志中自动记录 .NET Framework。如果您的控制台应用程序被执行,例如作为计划作业打印输出到控制台将不会对您有太大帮助。这是处理异常的最干净的方法:根本不处理,让您的应用程序崩溃,这样您就可以在应用程序事件日志中找出问题所在。

如果您在可执行文件之外部署用于发布版本的 pdb,您还可以获得行号和文件信息,这使得在大多数情况下很容易发现错误。

如果您的应用程序是关键任务或交付给客户,则可能需要使用一些日志框架来记录到一些私有日志文件。控制台应用程序和 Windows 应用程序之间的区别只是 PE 标头中的一个标志。Windows 应用程序将从当前启动的控制台分离,而控制台应用程序将保持连接到它。这是唯一的区别。您还可以在控制台应用程序中创建 WPF 应用程序,但只要它运行,它就会阻止您的控制台,这可能不是您想要的。

但是如果你切换到一个 Windows 应用程序,你可以分配一个新的控制台来使 Console.WriteLine 碰巧再次工作,你可以继续使用 printf 调试,这可能是最常用的调试方法,虽然是一种非常老式的方法。

通常你会在你的应用程序中添加一个跟踪库来遵循默认关闭的应用程序流程。还应该进行日志记录,它始终只进行错误记录。使用这种方法,如果错误日志记录不够,您可以在客户机器上使用更多故障排除选项。

于 2013-07-21T06:59:01.220 回答
0

如果你想使用 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";
});
于 2013-07-21T05:03:17.987 回答