在VS 2010中尝试/捕获不捕获异常

时间:2011-06-20 14:52:25

标签: c# wcf visual-studio-2010 try-catch

我在VS2010 C#中遇到了一个非常奇怪的事情。我正在使用WCF PubSub框架,通过netTcpBinding进行回调。奇怪的是,在我的大型解决方案中的一个代码块中抛出异常(我完全期望并且正在编写代码),但是调试器正在停止显示异常被抛出,好像没有try或catch。现在当我在VS之外运行应用程序只是.exe时,程序不会崩溃,并且相应地处理异常。更奇怪的是,当我在一个新的空白解决方案中创建了这个应用程序的轻量级版本时,在调试模式期间在VS中捕获了异常,但是当我再次将这个相同的轻量级项目添加到原始大型项目时,异常没有被捕获。这是代码块,虽然我认为这个问题与VS中的设置有关,但这是我唯一的猜测。

基本上,当客户端意外关闭并且服务尝试发送到有故障的客户端/订户时,catch将处理此问题并从列表中删除订户。 _subscribers列表是静态只读列表。我已经尝试制作服务单例并且不在列表中使用静态关键字,但它似乎没有区别。由于显而易见的原因,我无法压缩并发布其所在的整个解决方案。

public void UpdateData(Action<T> action)
{
 _subscribers.ForEach(subscriber =>
           {
               var client = subscriber as ICommunicationObject;
               try
               {
                 if (client != null && client.State == CommunicationState.Opened)
                     action(subscriber);
                 else
                     Unsubscribe(subscriber);
               }
               catch
               {
                 Unsubscribe(subscriber);
               }
            }
 );
}   

3 个答案:

答案 0 :(得分:2)

我会查看您的Exceptions设置。我会考虑用以下清洁逻辑替换:

           try
           {
             if (client != null && client.State == CommunicationState.Opened)
                 action(subscriber);

           }
           finally
           {
             Unsubscribe(subscriber);
           }

答案 1 :(得分:2)

海因兹上面的回答解决了这个问题,可以在这里解决:

http://stevesmithblog.com/blog/visual-studio-break-when-exception-thrown/

答案 2 :(得分:1)

Heinzi的答案链接已死,但已在此处存档:

https://web.archive.org/web/20120126024551/http://stevesmithblog.com/blog/visual-studio-break-when-exception-thrown/

这是文本的副本。 顺便说一句,这对我来说没有帮助...


出现异常时Visual Studio中断

默认情况下,Visual Studio仅在用户代码中未处理异常时才会中断。这通常与实际发生异常的地方相距一定距离,因为在此期间,在未处理异常之前,可能已经涉及了多个try ... catch块。如果开发人员确实希望确切地看到失败的代码行,则ALT.NET邮件列表上的最新线程讨论了一些解决此问题的技术。一种这样的技术(Jon Davis)使用预编译指令有条件地添加try-catch语句,如下所示:

void MyMethod()

    {
    #if !DEBUG
                    try 
                    {
    #endif
     
                                    // the logic that might throw
                                    DoSomething();
     
    #if !DEBUG
                    }
                    catch (Exception e)
                    {
                                    LogError(e);
                                    // etc…
                    }
    #endif
    }

这变得非常难看,但是可以完成工作。但是,另一位列表成员(Nick Blumhardt)写道并指出了Visual Studio的一项功能,如果这是所需的行为,它将有效地为您完成此操作。从“调试”菜单中,选择“例外”(或使用Ctrl-Alt-E),该对话框将出现:

图片

如果选中“引发公共语言运行时异常”下的框,则调试器将在发生它的行上中断,而不是在某些catch块中未对其进行处理时中断。使用此选项的不利之处在于它适用于所有代码,而不仅仅是特定的方法。如果您只想在引发异常时打破某些代码块,则可以混合使用两种技术,但我个人会避免使用前一种技术,因为我认为这会导致较难看的代码,并且行为不规范。开发中和生产中相同。

还值得指出的是,Visual Basic可以在{expression}时使用Catch Exception来轻松实现此目的。例如,DEBUG标志可用于When条件。这仍然会导致代码在DEBUG和生产之间的行为有所不同,但是至少它更优雅,更易于阅读和维护。不幸的是,C#缺少这种功能。