这是我的第一个正确处理异常的应用程序。这是一个WCF服务。以前所有其他的只是我自己的简单应用程序。我对C#中的异常处理知之甚少。
我有这样的代码:
MembershipUser memUser = Membership.GetUser(username);
DatabaseDataContext context = new DatabaseDataContext();
UserMembership user = UserMembership.getUserMembership(memUser);
ItemsForUser itemUser = Helper.createItemForUser(ref item, memUser);
Helper.setItemCreationInfo(ref item, user);
context.Items.InsertOnSubmit(item);
context.SubmitChanges();
在此代码中,可能会发生一些例外情况。比如NullReferenceException。我如何知道哪个对象导致了异常,因此我可以知道在catch中要做什么以及返回到客户端的内容?
答案 0 :(得分:9)
通常,您不应该捕获任何例外。
我知道这听起来很奇怪,但事实是你应该只捕捉你实际上可以做某些事情的例外情况,并且你通常无法对异常做任何事情。
此规则的“例外”与“处理”异常的含义有关。在某些应用程序中,“处理”异常意味着记录它。在其他(例如ASP.NET)中,最好不处理异常,因为框架(在本例中为ASP.NET Health Monitoring)将为您记录它。
在事件驱动的代码中,比如Windows Forms,我发现有必要在事件处理程序中捕获异常。至少在早期版本的.NET中,允许异常传播到例如按钮单击事件之外会产生令人不快的结果。我通常捕获异常并将其显示在对话框中。
在多层应用程序中,可能会捕获层边界上的异常,然后重新抛出新的特定于层的异常:
try
{
// ...
}
catch (Exception ex)
{
throw new TierException("Some message", ex);
}
另一个用例是捕获异常,然后抛出一个包含更多信息的新异常:
public int GetValueFromConfigurationFile(...)
{
const string configFileName = "...";
try
{
// ...
}
catch (FileNotFoundException fEx)
{
throw new InvalidOperationException(
String.Format("Can't find configuration file {0}", configFileName),
fEx);
}
}
在这种情况下,您正在捕获特定的异常(FileNotFoundException
),并提供他们无法知道的调用者信息:未找到的文件是配置文件。
一般信息是:
- 只捕获您知道如何处理的异常
- 尽可能抓住最具体的例外
- 在创建新异常时始终包含内部异常,以保留异常链
- 要重新抛出当前例外,请使用throw;
,而不是throw ex;
还有一些,我将尝试从Microsoft框架设计指南中找到您的参考。
P.S。如果有人能找到这个重复的问题,请随意关闭。我不介意失去任何代表。我找不到副本。
我应该刚刚发布了“异常处理”tag wiki的链接,其中包含:
但是,对于.NET程序上下文中的异常处理,请参阅 “Design Guidelines for Exceptions”。
答案 1 :(得分:1)
虽然WCF具有将服务器异常传递到客户端的机制,但是如果您的客户端用户真的希望看到他们脸上通常存在复杂的服务器端异常,则可能是值得考虑的。
通常更好地跟踪服务器端的预期 - 如果您想远程访问它,那么使用远程跟踪记录器。或者在服务器上有一个文本跟踪api,以不引人注目的方式记录服务器异常客户端。