11

Wiem, że mogę uniemożliwić debuggerowi Visual Studio zatrzymanie się na określonych rodzajach wyjątków, gdy są one wywoływane (za pośrednictwem okna dialogowego "Wyjątki" Ctrl-Alt-E). Ale co, jeśli chcesz kontrolować to z kodu, dla niektórych konkretnych miejsc, a nie na zasadzie wszystko albo nic? Na przykład:Selektywne zapobieganie zatrzymywaniu się debuggera przy wyjątkach pierwszej szansy

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) 
} 

używam hipotetycznego #pragma ignore aby zilustrować, co mam na myśli, ale nie coś takiego rzeczywiście istnieje?

UPDATE w celu odpowiedzi na pytanie "Niejasne, o co pytasz". Wypróbuj ten kod w debugerze: https://dotnetfiddle.net/npMk6r. Upewnij się, że wszystkie wyjątki są włączone w oknie dialogowym Ctrl-Alt-E. Debuger zatrzyma się na linii throw new OperationCanceledException("cancelled1") po każdej iteracji pętli. Nie chcę, żeby tak się stało, ponieważ jest to denerwujące. Jednak chcę, aby zatrzymał się na ostatnim rzucie poza pętlą, throw new OperationCanceledException("cancelled2") (lub gdziekolwiek indziej, o to chodzi).

+0

co jeśli po prostu pusty '' {} catch blok Próbował pan, że ..? – MethodMan

+0

@DJKRAZE, Debugger zatrzyma się na 'token.ThrowIfCancellationRequested()' tak czy inaczej, chyba że wyłączę 'OperationCancelledException' (lub' TaskCancelledException') w oknie dialogowym Ctrl-Alt-E. Nie chcę połknąć wyjątku, po prostu chcę, aby debugger zignorował go dla pewnych miejsc w moim kodzie, nie wszędzie. – avo

+0

Czy "DebuggerHiddenAttribute" będzie opłacalną opcją? – InBetween

Odpowiedz

5

Może to nie jest dokładnie to, czego szukasz, ale użyłbym do tego atrybutu DebuggerNonUserCode.

Oto przykład zmodyfikowanej wersji fiddle. Debugger nie zatrzyma się na ThrowIfCancellationRequested chociaż OperationCanceledException jest włączona w Ctrl + Alt + E dialogowym Wyjątki.

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; 
      } 
     } 
    } 
} 

Oczywiście, można mieć używane CancellationToken.IsCancellationRequested zamiast ThrowIfCancellationRequested w tym konkretnym przypadku, ale powyższe podejście ilustruje koncepcję, która może być rozszerzona do każdego innego wyjątku.

+0

To jest bardzo interesujące, dziękuję @Noserati. Czy myślisz, że możliwe jest stworzenie ogólnej wersji metody podobnej do "TryThrowIfCancellationRequested", coś, co mógłbym przekazać jako "Akcja" i typ wyjątku do zignorowania? – avo

+1

@avo, nie sądzę, ponieważ 'DebuggerNonUserCode' nie można zastosować do lambda. Jeśli wrzucisz do lambda, debugger się zatrzyma. O ile nie zdefiniujesz faktycznej metody dla każdego lambda, w takim przypadku może zadziałać. Nie trzeba chyba dodawać, że przez "ignorowanie" rozumiesz "manipulowanie/rejestrowanie" wyjątku, prawda? – Noseratio

-1

Co chcesz może być wyrażona jako

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

Ale to jest uważane za złą praktyką. Wyjątki powinny być w jakiś sposób obsługiwane. Przynajmniej z niektórych powodów debugowania.

+1

Debugger zatrzyma się na 'token.ThrowIfCancellationRequested()' tak czy inaczej, chyba że wyłączę 'OperationCancelledException' (lub' TaskCancelledException') w oknie dialogowym Ctrl-Alt-E. Nie chcę połknąć wyjątku, po prostu chcę, aby debugger zignorował go dla pewnych miejsc w moim kodzie, nie wszędzie. – avo

+0

więc ... ale jeśli nie masz kodu do wykonania, nic się nie stanie, więc posiadanie go bez kodu nic nie da. – MethodMan

+4

@DJKRAZE: On nie chce, żeby debugger się zepsuł. – SLaks

0

spróbować następujący sposób:

Kiedy „Just My Code” jest włączona, Visual Studio, w niektórych przypadkach złamie się na linii, która zgłasza wyjątek i wyświetla komunikat o błędzie „wyjątek nie obchodzić według kodu użytkownika. " Ten błąd jest łagodny. Możesz nacisnąć klawisz F5, aby kontynuować i zobaczyć zachowanie związane z wyjątkami, które zostało zademonstrowane w poniższych przykładach. Aby uniemożliwić programowi Visual Studio złamanie pierwszego błędu, odznacz pole wyboru "Just My Code" w obszarze Tools, Options, Debugging, General.

z here

nadziei, że to pomoże