11

我知道我可以防止Visual Studio调试器在引发某些异常(通过Ctrl-Alt-E“Exceptions”对话框)时停止某些异常。但是如果想要从代码控制这个,对于某些特定的地方而不是全部或者没有基础呢?例如:有选择地阻止调试器在第一次出现异常时停止

try 
{ 
    SomeMethod(token); 
} 
catch (OperationCancelledException) 
{ 
    return false; 
} 

// ... 

void SomeMethod(CancellationToken token) 
{ 
    // ... 

    // I don't want the debugger to stop on the following line 
    #pragma ignore(OperationCancelledException, true) 
    token.ThrowIfCancellationRequested(); 
    #pragma ignore(OperationCancelledException, false) 
} 

我用假想#pragma ignore来说明我的意思,但这样的事情确实存在?

更新解决“不清楚你要求的”封闭投票。在调试器中尝试下面的代码:https://dotnetfiddle.net/npMk6r。确保在Ctrl-Alt-E对话框中启用了所有例外。在循环的每次迭代中,调试器将停止在throw new OperationCanceledException("cancelled1")行。我不想让它发生,因为它很烦人。然而,我确实希望它停止在循环外的最后一圈,throw new OperationCanceledException("cancelled2")(或其他任何地方)。

+0

如果你只是有一个空的'抓{}'块你有没有尝试过的..? – MethodMan 2014-10-08 21:20:23

+0

@DJKRAZE,除非我在Ctrl-Alt-E对话框中禁用'OperationCancelledException'(或'TaskCancelledException'),否则调试器将停止在'token.ThrowIfCancellationRequested()'上。我不想吞下异常,我只是希望调试器在我的代码中的某些地方忽略它,而不是到处都是。 – avo 2014-10-08 21:24:32

+0

'DebuggerHiddenAttribute'是否可行? – InBetween 2014-10-08 22:02:01

回答

5

这可能不是你正在寻找的东西,但我会用DebuggerNonUserCode这个属性。

为了说明这一点,下面是您的fiddle的修改版本。调试器不会停止在ThrowIfCancellationRequested即使OperationCanceledException按Ctrl + Alt键+Ë例外对话框中启用。

using System; 
using System.Diagnostics; 
using System.Threading; 

namespace TestApp 
{ 
    static class Ext 
    { 
     [System.Diagnostics.DebuggerNonUserCode()] 
     public static bool TryThrowIfCancellationRequested(
      this CancellationToken token) 
     { 
      try 
      { 
       // debugger won't stop here, because of DebuggerNonUserCode attr 
       token.ThrowIfCancellationRequested(); 
       return true; 
      } 
      catch (OperationCanceledException) 
      { 
       return false; 
      } 
     } 
    } 

    public class Program 
    { 
     static bool SomeMethod(CancellationToken token) 
     { 
      System.Threading.Thread.Sleep(1000); 
      return token.TryThrowIfCancellationRequested(); 
     } 

     public static void Main() 
     { 
      var cts = new CancellationTokenSource(1000); 

      for (var i = 0; i < 10; i++) 
      { 
       if (!SomeMethod(cts.Token)) 
        break; 
      } 
     } 
    } 
} 

当然,你可以在这个特定的情况下使用CancellationToken.IsCancellationRequested代替ThrowIfCancellationRequested,但上面的方法说明可扩展到任何其他异常的概念。

+0

这非常有趣,谢谢@Noserati。你认为可以创建一个'TryThrowIfCancellationRequested'类方法的通用版本,我可以传递一个'Action'和一个要忽略的异常类型? – avo 2014-10-08 22:58:21

+1

@avo,我不这么认为,因为'DebuggerNonUserCode'不能应用于lambda。如果你抛出lambda,调试器将停止。除非你为每个lambda定义了一个实际的方法,在这种情况下它可能工作。不用说,我想通过“忽略”你的意思是“处理/记录”某种异常,对吧? – Noseratio 2014-10-08 23:02:40

-1

你想要什么可以表示为

try 
{ // #pragma ignore(OperationCancelledException, true) 
    token.ThrowIfCancellationRequested(); 
} 
catch (OperationCancelledException op) 
{ // #pragma ignore(OperationCancelledException, false) 
    // ignore 
} 

但是,这被认为是不好的做法。例外情况应该以某种方式处理。至少由于某些调试原因。

+1

无论如何,除非我在Ctrl-Alt-E对话框中禁用'OperationCancelledException'(或'TaskCancelledException'),否则调试器将停止在'token.ThrowIfCancellationRequested()'上。我不想吞下异常,我只是希望调试器在我的代码中的某些地方忽略它,而不是到处都是。 – avo 2014-10-08 21:21:45

+0

so..but如果你没有代码执行那里没有任何事情会发生,所以它没有代码将不会做任何事情.. – MethodMan 2014-10-08 21:22:43

+4

@DJKRAZE:他不希望调试器中断。 – SLaks 2014-10-08 21:23:06

0

您尝试以下方法:

启用“仅我的代码”时,Visual Studio在某些情况下会打破抛出异常的行并显示,上面写着“异常不处理错误消息通过用户代码“。这个错误是良性的。您可以按F5键继续,并查看下面示例中演示的异常处理行为。 为防止Visual Studio突破第一个错误,只需取消选中Tools,Options,Debugging,General下的“Just My Code”复选框。

here

希望这有助于