C# 将异常冒泡到堆栈顶部可以吗?

C# 将异常冒泡到堆栈顶部可以吗?,c#,.net,wcf,exception-handling,C#,.net,Wcf,Exception Handling,让异常冒泡到堆栈顶部,而不是在每个方法中捕获它,这样可以吗?。。我们无论如何都应该这样做吗此方法是否存在任何细微问题或副作用(例如,丢失异常详细信息、堆栈跟踪或内部异常详细信息等)? 虽然我的问题是一般性的,但我目前的情况如下: 我正在将现有的WSE3 web服务移动到WCF,因此y客户机就是WSE3客户机 我添加了一个行为,以便无论何时在WCF服务中发生故障异常,都会将其传递给客户端。当OperationContract方法中出现异常时,我会在客户端毫无问题地收到异常消息。但是,每当它出现在

让异常冒泡到堆栈顶部,而不是在每个方法中捕获它,这样可以吗?。。我们无论如何都应该这样做吗此方法是否存在任何细微问题或副作用(例如,丢失异常详细信息、堆栈跟踪或内部异常详细信息等)?


虽然我的问题是一般性的,但我目前的情况如下:

我正在将现有的WSE3 web服务移动到WCF,因此y客户机就是WSE3客户机

我添加了一个行为,以便无论何时在WCF服务中发生
故障异常
,都会将其传递给客户端。当
OperationContract
方法中出现异常时,我会在客户端毫无问题地收到异常消息。但是,每当它出现在
操作契约
s以外的方法中时,我总会遇到与安全相关的问题。我无法确定确切的原因


然而,作为一种解决方法,我认为只从
OperationContract
抛出异常,让异常冒泡到
OperationContract
绝对是这样,这就是它们的目的。经验法则是捕捉异常,在这里您可以明智地尝试继续。因此,如果你得到了类似内存不足的东西,让它冒泡并终止程序;如果在迭代大量数据时得到一个除以零的结果,则在可以继续下一个数据的地方捕获它

更新

对于您的问题,否,所有详细信息(包括引发异常的堆栈跟踪)都将与异常对象一起传播

你有时会看到类似的东西

highLevelFunction(){
   try {
     lowerLevelFunction();
   } catch (LowLevelException e){
     throw HighLevelException(e);
   }
}
或者异常链接。这里发生的是一些低级异常,比如“除以零”;捕捉它并引发一个新的异常,如“数据异常”,以使它对调用
highLevelFunction
的例程更有意义

(请原谅,如果这不是完美的C#语法,我最近没有写太多。)

让异常冒泡而不是在每个方法中捕获它可以吗

请不要在每种方法中都抓住例外如果可以使用异常执行一些有用的操作,则应仅捕获异常,例如:

  • 处理它(即不重新旋转它)
  • 添加一些重要的上下文信息
我维护的应用程序中,每个nethod都有一个
try-catch
块,我的意思是每个方法:

捕获这样的异常是完全没有意义的,除了使代码更难阅读和异常更难跟踪之外,什么也做不了

如果异常必须通过某个进程间边界(例如在WCF服务中),那么在异常向外界公开的时候,您可能希望首先捕获、记录异常,然后以IPC边界的兼容格式重新显示异常,以便在服务中记录所有故障


然而,在许多情况下,有一种专门为此目的而设计的替代机制——WCF有一个接口,可以注册该接口,以便以一致的方式捕获和记录所有未处理的异常,而无需在每个公开的方法中使用try-catch块。

如果您有完整的应用程序(GUI、业务、数据)让它冒泡到UI并在事件中处理它。这使您有机会同时向用户显示消息。它还将其捕捉到动作原点(即,当用户执行动作X时,此动作发生)。在每个方法中捕获它都是CPU密集型的,而且没有必要,因为您可以只记录stacktrace来查找源代码。如果您正在制作中间件应用程序,那么请尝试在接口处处理它,或者将其冒泡出来,具体取决于中间件的使用方式。

谢谢您的回答。但是会不会有任何副作用,比如(不知何故)丢失异常细节?在web服务方法(SOAP)中,我的做法与上面的代码类似:
尝试{…}catch(异常x){log(x);throw;}
在服务器上进行更多日志记录。我的经验是,登录到我这一边,而不是SOAP服务的客户/用户那一边,对我帮助很大。谢谢你的回答。但是会不会有任何副作用,比如(不知何故)丢失异常细节?或者如果您能想到的其他事情。@CSharpLearner如果您正在跨越IPC边界(例如通过SOAP web服务),那么您可能希望添加try-catch块,但是许多框架提供了一种更灵活的方法来控制和记录抛出的异常,例如WCF提供了接口。这就是您所想的吗?我已经实现了
IErrorHandler
,并且仅使用该实现。但我仍然面临这个问题。我怀疑这是因为WSE3客户端(不是WCF客户端)与WCF服务通信。@CSharpLearner您有任何具体的例子吗?您可能希望使用类似的方法跟踪异常,以查看是否正在发送信息,从而确定问题是出在客户端还是服务器上。
public void DoSomething()
{
    try
    {
        throw new NotImplementedException();
    }
    catch (Exception ex)
    {
        throw ExceptionHandler.CreateException(ex, "DoSomething");
    }
}