C# 选择性地防止调试器在第一次出现异常时停止

C# 选择性地防止调试器在第一次出现异常时停止,c#,.net,visual-studio,task-parallel-library,visual-studio-debugging,C#,.net,Visual Studio,Task Parallel Library,Visual Studio Debugging,我知道我可以防止VisualStudio调试器在抛出某些类型的异常时停止(通过Ctrl-Alt-E“exceptions”对话框)。但是,如果您想从代码中控制这一点,针对某些特定的位置,而不是基于“全部”或“无”的基础,该怎么办?例如: try { SomeMethod(token); } catch (OperationCancelledException) { return false; } // ... void SomeMethod(CancellationToken

我知道我可以防止VisualStudio调试器在抛出某些类型的异常时停止(通过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
来说明我的意思,但是像这样的东西真的存在吗


更新以解决“不清楚你在问什么”的结束投票。请在调试器中尝试以下代码:。确保在Ctrl-Alt-E对话框中启用了所有异常。每次循环迭代时,调试器将在抛出新操作CanceledException(“Canceled1”)行上停止。我不想发生这种事,因为这很烦人。然而,我确实希望它在循环外的最后一次抛出时停止,
抛出新操作CanceledException(“Canceled2”)
(或者在其他任何地方)

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

但这被认为是一种不好的做法。应该以某种方式处理异常。至少出于一些调试原因。

这可能不是您想要的,但我会使用这个属性

为了说明这一点,这里是您的。即使在Ctrl+Alt+E Exceptions对话框中启用了
OperationCanceledException
,调试器也不会在请求的
上停止

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;
            }
        }
    }
}
使用系统;
使用系统诊断;
使用系统线程;
命名空间TestApp
{
静态类扩展
{
[System.Diagnostics.DebuggerNonUserCode()]
请求公共静态bool trythrowifcancellation(
此CancellationToken(令牌)
{
尝试
{
//调试器不会在此停止,因为DebuggerNonUserCode属性
token.ThrowIfCancellationRequested();
返回true;
}
捕获(操作取消异常)
{
返回false;
}
}
}
公共课程
{
静态布尔方法(CancellationToken令牌)
{
系统线程线程睡眠(1000);
return token.TryThrowIfCancellationRequested();
}
公共静态void Main()
{
var cts=新的CancellationTokenSource(1000);
对于(变量i=0;i<10;i++)
{
if(!SomeMethod(cts.Token))
打破
}
}
}
}

当然,在这种特殊情况下,您可以使用
CancellationToken.IsCancellationRequested
而不是
ThrowifcCancellationRequested
,但上述方法说明了可以扩展到任何其他异常的概念。

您可以尝试以下方法:

当启用“仅我的代码”时,Visual Studio在某些情况下会在引发异常的行上中断,并显示一条错误消息,上面显示“异常未由用户代码处理”。此错误是良性的。您可以按F5键继续,并查看下面示例中演示的异常处理行为要防止Visual Studio在出现第一个错误时出错,只需取消选中“工具、选项、调试、常规”下的“仅我的代码”复选框


希望这有帮助

如果您只是有一个空的
catch{}
块,您尝试过吗?@DJKRAZE,调试器将在
token.throwifcancellationrequest()
上停止,除非我在Ctrl-Alt-E对话框中禁用
操作取消异常
(或
任务取消异常
)。我不想接受异常,我只希望调试器在我代码中的某些位置忽略它,而不是在所有位置。是否可以选择
DebuggerHiddenAttribute
执行异常?在Visual Studio中,可以设置断点来执行异常。它们被称为跟踪点。也许可以使用跟踪点来更改异常的设置。不过,我不知道如何操作,而且VS2012及更高版本中没有宏,因此这是一个很长的过程。调试器将在
标记上停止。无论如何,除非我在Ctrl-Alt-E对话框中禁用
操作取消异常
(或
任务取消异常
)。我不想接受异常,我只希望调试器在代码中的某些地方忽略它,不是所有的地方。所以..但是如果你没有代码来执行,那么什么都不会发生,所以没有代码就没有任何作用。@DJKRAZE:他不想让调试器坏掉。他可以使用一些#如果有条件的话定义的,然后检查debuger或类似的东西吗?我想我理解你想要什么。一些细粒度的方法只是隐藏一些任意代码块的异常。据我所知,这只能通过处理异常并在调试器异常对话框中将异常设置为未处理的异常来实现。这非常有趣,谢谢@Noserati。你认为有可能创建一个类似
trythrowifcancellationrequest
的方法的通用版本吗?我可以将
操作和一种要忽略的异常传递给@avo,我不这么认为,因为
DebuggerNonUserCode
不能应用于lambda。如果在lambda中抛出,调试器将停止。除非为每个lambda定义一个实际的方法,否则在这种情况下它可能会工作。不用说,我想“忽略”的意思是“处理/记录”异常,对吗?