I know I can prevent the Visual Studio debugger from stopping on certain kind of exceptions when they're thrown (via the Ctrl-Alt-E "Exceptions" dialog). But what if want to control this from code, for some specific places rather than on the all-or-none basis? For example:
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)
}
I use the hypothetic #pragma ignore
to illustrate what I mean, but does something like this actually exist?
UPDATE to address "Unclear what you're asking" closure vote. Try this code in the debugger: https://dotnetfiddle.net/npMk6r. Make sure all exceptions are enabled in the Ctrl-Alt-E dialog. The debugger will be stopping on the throw new OperationCanceledException("cancelled1")
line upon each iteration of the loop. I don't want that to happen as it's annoying. Yet, I do want it to stop on the last throw outside the loop, throw new OperationCanceledException("cancelled2")
(or anywhere else, for that matter).
This might not be exactly what you're looking for, but I'd use DebuggerNonUserCode
attribute for this.
To illustrate that, here's a modified version of your fiddle. The debugger won't stop on ThrowIfCancellationRequested
even though OperationCanceledException
is enabled in the Ctrl+Alt+E Exceptions dialog.
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;
}
}
}
}
Of course, you could have used CancellationToken.IsCancellationRequested
instead of ThrowIfCancellationRequested
in this particular case, but the above approach illustrates the concept which can be extended to any other exception.