7

我现在正处于跨平台移动应用程序开发的一个非常关键的十字路口,并且真的可以使用一些专业知识(比如哇)。

为了提供一些上下文(我希望这可能有助于回答),我正在使用 VS2010U(不是 MonoDevelop,但它是针对 IOS),基于方便的 MonoCross 框架在 .NET 中开发一个移动应用程序。第一个目标平台是 Android,然后是 IOS 和 Windows Phone 的“端口”(如果我做对了,就不是真的)。

现在我已经奠定了坚实的基础,包括业务逻辑、数据访问层、数据库、REST Web 服务等,我正在经历并尝试处理一些错误,但我不确定最好的方法是什么是。

有人告诉我,try-catch 块可能会影响性能(在这种情况下这很重要),
这是真的吗?我应该谨慎地使用它们,还是只是在可能引发异常的地方拍打它们(我有点想在我所有的 SQLite API 调用中使用它们,因为我不知道他们到底在做什么)。

使用事件回调对错误处理来说是一件坏事吗?出于性能原因,我被建议尽可能使用这些,而不是 try-catch,但我不想破坏任何设计原则和范式,最终导致到处都是草率的代码。

第三个选项是状态字段和返回值,它的开销最少,但处理起来非常烦人。

那么你们怎么看?我想我只是在寻找一些大体方向,也许是关于在哪里和何时使用它们的一些建议,以及我最有可能遗漏的任何其他技术。如果需要更多详细信息,请告诉我,因为我很乐意提供。

感谢您为此抽出一些时间!

4

4 回答 4

4

我认为让你的程序变得丑陋的原因是到处都在进行异常处理,尽管我们有很好的异常处理模式。

这些将在您的代码库中发生的功能称为横切关注点,例如日志记录、安全性、审计、异常处理和......

您可以在这里找到好的模式http://msdn.microsoft.com/en-us/library/ee658105.aspx#ExceptionManagement

值得一提的是,我不建议按照 Microsoft 文档中的建议使用 EntLib。

如果您寻找面向方面的编程(AOP),您会找到很好的资源。最后的提示是实现将使用依赖注入/IoC 框架来解决这些问题。

于 2012-07-03T19:54:11.987 回答
2

我有点想在我所有的 SQLite API 调用中使用它们,因为我不知道他们到底在做什么。

如果你说你正在使用一个库来与 SQLite 交互,那么这个库 API 很可能已经在某些错误情况下抛出异常。当然,在这种情况下,您应该在这些调用周围使用 try/catch 并处理这些错误情况。

当您自己没有编写该代码时,当您使用其他人的库时,总是会出现这种情况。

如何处理这些错误是您的决定。

我的建议:

  • 在大多数情况下,我反对回调/事件。当导致错误的 API 是异步的并且程序流程已经不言自明时,应该主要使用这些。
  • 抛出异常确实比状态码/返回值慢,但它可以安全地用于当今任何移动平台上,在应用程序不是时间关键的任何情况下。手机游戏使用异常抛出,它们是时间关键的(有点)。
  • 抛出异常提供了更好的代码可读性——在我看来,这是一个主观的事情——并且是在发生错误时跳出当前上下文的好方法。
于 2012-07-03T20:18:37.457 回答
1

try/catch当你想捕捉预期的异常时使用incase 。通常通过异常确定工作流不是好的选择,但它可能是 IO 操作的唯一选择。例如,您写入某个突然失去连接的外部设备。在这种情况下,您的程序将收到异常,但必须像处理通常的错误一样处理它。

于 2012-07-03T19:44:52.000 回答
1

有时理论与特定的实现并不相符,但我想 Mono 的这些概念已经存在一段时间了。

适当的运行时总是有利于无异常情况下的性能。理想情况下,在没有抛出异常的情况下,try/catch 块应该像 try 块的内容自己执行一样执行,而 try/finally 块应该像 try 和 finally 块的内容一样执行按顺序执行。当使用 CIL 字节码解释器时,通常不可能像我在这里提到的那样在没有开销的情况下执行这些操作。然而,一个像样的 JIT 或 AOT 编译器(就像你使用 Mono 获得的那样)实际上生成的代码在无异常情况下运行的速度与省略 try/catch/finally 构造时一样快。¹

如果您改为选择错误代码策略,您的应用程序将最终执行部分错误处理代码,即使没有发生错误(将额外参数传递给方法,计算和测试返回代码等)。因此,您的目标是将异常处理的使用限制在真正的异常情况下。这种策略导致了一个健壮的应用程序(正确的错误处理),而不会降低性能关键成功案例的性能。

¹ 对于嵌入在数值计算循环主体中的 try/finally 块而言,这并不是 100% 准确的,但在正确用于处理异常情况时,它对性能产生明显影响的可能性在这一点上几乎为零。具体来说,与没有 try/finally 块的相同方法相比,为 X86 编译的 try/finally 块 JIT 将包含类似于 push/pop/jmp(本地分支)指令的代码。这比调用定义为的方法的开销要小:public static void Foo() {}

于 2012-07-03T20:34:32.170 回答