C# 6.0 Exception Filter and when Keyword

C# 6.0 introduces a new feature exception filter and a new keyword when. Many C# features/keywords are syntactic sugars, but exception filter/when keyword is not.

To examine this feature, a few helper methods can be created:

internal static partial class ExceptionFilter
{
    private static void A() => B();

    private static void B() => C();

    private static void C() => D();

    private static void D()
    {
        int localVariable1 = 1;
        int localVariable2 = 2;
        int localVariable3 = 3;
        int localVariable4 = 4;
        int localVariable5 = 5;
        throw new OperationCanceledException(nameof(ExceptionFilter));
    }

    private static bool Log(this object message, bool result = false)
    {
        Trace.WriteLine(message);
        return result;
    }
}

These methods can make up a call stack, with some local variables. The Log method can log a Exception object and return a specified bool value.

Syntax

The when keyword works like if. A when condition is a predicate expression, which can be appended to a catch block. If the predicate expression is evaluated to be true, the associated catch block is executed; otherwise, the catch block is ignored.

private static void Filter()
{
    try
    {
        A();
    }
    catch (OperationCanceledException exception) when (string.Equals(nameof(ExceptionFilter), exception.Message, StringComparison.Ordinal))
    {
    }
}

In the earlier preview of C# 6.0, the if keyword was used. In the final release, if is replaced by when, because some improper format can make catch-if confusing, e.g.:

private static void Filter()
{
    try
    {
        A();
    }
    catch (OperationCanceledException exception) 
 // {
        if (string.Equals(nameof(ExceptionFilter), exception.Message, StringComparison.Ordinal))
        {
        }
 // }
}

The above code format looks just like a if statement inside the catch block.

Now it is already March 2016, the MSDN document for C# exception filter still uses the if keyword in the examples:

image

Compilation

Before C# 6.0, it is very common to catch an exception, then log or filter it, and re-throw:

private static void Catch()
{
    try
    {
        A();
    }
    catch (Exception exception)
    {
        exception.Log();
        throw;
    }
}

C# 6.0 provides a way to log or filter an exception before catching it:

private static void When()
{
    try
    {
        A();
    }
    catch (Exception exception) when (exception.Log())
    {
    }
}

Here the Log method will log the exception, and return false. So the catch block will not be executed.

ILSpy and ildasm (located in C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.6.1 Tools\) can be used to view the compiled IL. In the Catch method, the catch-log-throw pattern will be compiled to:

.method private hidebysig static void  Catch() cil managed
{
    .maxstack  2
    .locals init ([0] class [mscorlib]System.Exception exception)
    IL_0000:  nop
    .try
    {
        IL_0001:  nop
        IL_0002:  call       void Dixin.Console.Program::A()
        IL_0007:  nop
        IL_0008:  nop
        IL_0009:  leave.s    IL_0017
    }  // end .try
    catch [mscorlib]System.Exception 
    {
        IL_000b:  stloc.0
        IL_000c:  nop
        IL_000d:  ldloc.0
        IL_000e:  ldc.i4.0
        IL_000f:  call       bool Dixin.Console.Program::Log(object,
                                                            bool)
        IL_0014:  pop
        IL_0015:  rethrow
    }  // end handler
    IL_0017:  ret
} // end of method Program::Catch

There is nothing new or surprising. And When method is compiled to:

.method private hidebysig static void  When() cil managed
{
    .maxstack  2
    .locals init ([0] class [mscorlib]System.Exception exception,
                [1] bool V_1)
    IL_0000:  nop
    .try
    {
        IL_0001:  nop
        IL_0002:  call       void Dixin.Console.Program::A()
        IL_0007:  nop
        IL_0008:  nop
        IL_0009:  leave.s    IL_002a

    }  // end .try
    filter
    {
        IL_000b:  isinst     [mscorlib]System.Exception
        IL_0010:  dup
        IL_0011:  brtrue.s   IL_0017

        IL_0013:  pop
        IL_0014:  ldc.i4.0
        IL_0015:  br.s       IL_0024

        IL_0017:  stloc.0
        IL_0018:  ldloc.0
        IL_0019:  ldc.i4.0
        IL_001a:  call       bool Dixin.Console.Program::Log(object,
                                                            bool)
        IL_001f:  stloc.1
        IL_0020:  ldloc.1
        IL_0021:  ldc.i4.0
        IL_0022:  cgt.un
        IL_0024:  endfilter
    }  // end filter
    {  // handler
        IL_0026:  pop
        IL_0027:  nop
        IL_0028:  rethrow
    }  // end handler
    IL_002a:  ret
} // end of method Program::When

The catch keyword is gone, and C# when condition is compiled to a IL filter block. In the filter block, it checks if the exception is of Exception type. If so, it calls the Log method. Apparently, exception filter is not syntactic sugar. It is a CLR feature.

Runtime: stack unwinding

The catch block and when predicate refers to the same exception object. In the following example:

internal static void Log()
{
    try
    {
        A();
    }
    catch (Exception exception) when (exception.Log(true))
    {
        exception.Log();
        throw;
    }
}

In the when predicate, the Log method returns true, so in the catch block, Log will be called again. These 2 Log calls print out exactly the same information:

System.OperationCanceledException: ExceptionFilter
    at Dixin.Common.ExceptionFilter.D() in D:\OneDrive\Works\Drafts\CodeSnippets\Dixin\Common\ExceptionFilter.cs:line 21
    at Dixin.Common.ExceptionFilter.C() in D:\OneDrive\Works\Drafts\CodeSnippets\Dixin\Common\ExceptionFilter.cs:line 12
    at Dixin.Common.ExceptionFilter.B() in D:\OneDrive\Works\Drafts\CodeSnippets\Dixin\Common\ExceptionFilter.cs:line 10
    at Dixin.Common.ExceptionFilter.A() in D:\OneDrive\Works\Drafts\CodeSnippets\Dixin\Common\ExceptionFilter.cs:line 8
    at Dixin.Common.ExceptionFilter.Log() in D:\OneDrive\Works\Drafts\CodeSnippets\Dixin\Common\ExceptionFilter.cs:line 91

Apparently, in both cases, the exception object’s StackTrace property has the call stack of A/B/C/D methods, as expected.

The real difference is the CLR stack (not the exception object’s StackTrace string property). To demonstrate this, set 2 breakpoints at 2 Log calls:

image

When the exception filter is executed:

image

The current stack (again, not the exception object’s StackTrace property) is:

ConsoleApplication2.exe!Dixin.Common.ExceptionFilter.Log() Line 93
[Native to Managed Transition]   
ConsoleApplication2.exe!Dixin.Common.ExceptionFilter.D() Line 21
ConsoleApplication2.exe!Dixin.Common.ExceptionFilter.C() Line 12
ConsoleApplication2.exe!Dixin.Common.ExceptionFilter.B() Line 10
ConsoleApplication2.exe!Dixin.Common.ExceptionFilter.A() Line 8
ConsoleApplication2.exe!Dixin.Common.ExceptionFilter.Log() Line 91
ConsoleApplication2.exe!Dixin.Console.Program.Main() Line 110

Next, when the catch block is executed:

image

The current stack becomes:

ConsoleApplication2.exe!Dixin.Common.ExceptionFilter.Log() Line 95
ConsoleApplication2.exe!Dixin.Console.Program.Main() Line 110

This magic here is called stack unwinding: exception filter does not unwind the stack, and catch block does unwind. When executing catch block, this catch block’s method becomes the top frame of the stack. As a result, all the methods called by current method are removed from the stack. In contrast, exception filter can be helpful for runtime debugging. For example, if above Catch method is executed:

private static void Catch()
{
    try
    {
        A();
    }
    catch (Exception exception)
    {
        exception.Log();
        throw;
    }
}

at runtime the debugger breaks at the throw statement in the catch block:

image

The stack is unwound. As a result the debugger cannot see the exception is actually thrown by D.

When executing the other When method:

private static void When()
{
    try
    {
        A();
    }
    catch (Exception exception) when (exception.Log())
    {
    }
}

The Log method always returns false, so that the stack will not be unwound by catch block. This time the debugger breaks in method D, where the exception is actually thrown:

image

Notice in the Locals windows and Call Stack window, all information are available for debugger.

Conclusion

C# 6.0 exception filter and when keyword is not a syntactic sugar. It is a CLR feature. Unlike catch block, exception filter does not unwind the call stack, which is helpful at runtime.

29 Comments

  • awesome, great explanation!

  • Great

  • https://ma-study.blogspot.com/

  • Thank you for this amazing article.

  • Umfangreiche Bibliothek: Aniworld verfügt über eine umfangreiche Bibliothek mit Anime-Titeln, die Fans auf der ganzen Welt ansprechen. Es gibt eine große Auswahl an Genres wie Action, Abenteuer, Drama, Fantasy, Horror und mehr.

  • Blockieren Sie unerwünschte E-Mails mit der Spam-Filterung Verwalten Sie mehrere E-Mail-Konten in einem einzigen Hotmail-Konto.Richten Sie benutzerdefinierte Signaturen für Ihre E-Mails ein.Verwenden Sie das Kalender-Feature, um Ihre Termine zu organisieren.

  • Die Kalenderfunktion von Web.de ist auch sehr nützlich, da sie es Nutzern ermöglicht, Termine und Veranstaltungen zu speichern und zu organisieren. Der Kalender kann auch mit anderen https://iwebde.de/ Nutzern geteilt werden, was die Organisation von Gruppenterminen erleichtert.

  • Insgesamt ist Unitymedia Webmail eine leistungsstarke und benutzerfreundliche Plattform, die alle wesentlichen E-Mail-Funktionen bietet, die Sie benötigen, um Ihre E-Mails auf einfache und bequeme Weise zu verwalten.



  • Ein weiterer Grund, warum Streamkiste bei den Nutzern so beliebt ist, liegt in der hohen Videoqualität und dem schnellen <a href="https://streamkisteto.de/">streamkiste. tv</a> Erlebnis. Die Plattform bietet Inhalte in verschiedenen Auflösungen, einschließlich HD und Full HD, um sicherzustellen, dass Sie Ihre Lieblingsfilme und -serien in bester Qualität genießen können. Darüber hinaus ist das Streaming auf Streamkiste in der Regel reibungslos und unterbruchsfrei, was ein nahtloses und angenehmes Seherlebnis ermöglicht.

  • Der Web.de Freemail-Dienst bietet seinen Nutzern eine bequeme Möglichkeit, ihre E-Mails zu verwalten und auf wichtige Informationen zuzugreifen. In diesem Artikel werden wir Ihnen zeigen, wie Sie sich bei Web.de anmelden und auf Ihr persönliches E-Mail-Konto zugreifen können.

  • Gli utenti possono creare segnalibri per tenere traccia de <a href="https://accedilog.com/millebook-accedi-guida/">millebook accedi</a> i passaggi preferiti, effettuare ricerche all'interno dei libri per trovare specifici argomenti o citazioni e persino accedere a raccomandazioni personalizzate in base ai loro interessi di lettura. Queste funzionalità rendono la lettura interattiva e coinvolgente, offrendo agli utenti un modo unico

  • Los hablantes de catalán han identificado la pérdida de su lengua como un problema serio y, gracias a la colaboración con programadores, han creado este juego viral para abordar esta preocupación. El Paraulògic es un ejemplo inspirador que otros países pueden aprender, promoviendo iniciativas similares para que los jóvenes conozcan su propia cultura, idioma y civilización ancestral.

  • La plateforme permet non seulement de <a href="https://frenchstreamfr.com">
    frenchstream.life</a> visionner des films et des séries, mais également de télécharger des émissions pour les regarder hors ligne.
    Aucune inscription ni abonnement n'est nécessaire avant d'utiliser l'application.
    L'application de streaming est disponible gratuitement, sans aucune interruption, vous pouvez donc regarder votre contenu préféré sans soucis.

  • Nachdem du dich erfolgreich bei AniWorld angemeldet hast, kannst du nun die umfangreiche Anime-Sammlung erkunden. Du kannst entweder nach bestimmten Anime-Titeln suchen oder durch verschiedene Kategorien stöbern, wie z.B. Action, Romance, Fantasy, oder Comedy. Mit über 1.000 Anime-Streams gibt es mit Sicherheit für jeden Geschmack etwas dabei!

  • O Scarlet iOS oferece uma plataforma personalizada e inovadora para usuários interessados em instalar aplicativos com jailbreak em dispositivos não-jailbroken. Isso amplia as possibilidades para os usuários e permite que eles explorem uma variedade maior de aplicativos.

  • Quando comunichi con un'altra persona su un determinato argomento <a href="https://itpostaa.com">gmail.com</a> o evento, Gmail Sign in organizza automaticamente le conversazioni. Aiuta a mantenere la tua casella di posta più ordinata.

  • Nice article and to the point. Sadly not many people use the exception filter. One tip: Always end with the empty Exception (no filter). This way you will always catch unexpected exceptions.

  • <a href="https://wordlegalegoes.com">wordle gallego jugar</a> una experiencia única y emocionante para todos aquellos que disfrutan del poder y la magia de las palabras. Participa en este desafío lingüístico y gana la oportunidad de vivir una experiencia inolvidable que marcará tu vida. ¡Inscríbete ahora y prepárate para jugar con las palabras en WordLegal España! ¡Buena suerte!

  • Partidos en vivo <a href="https://viperplayes.com">viperplay net</a> Disfruta de la emoción de los partidos en tiempo real. Viper Play Net Fútbol TV te permite ver partidos en vivo y seguir el desarrollo de los encuentros mientras ocurren.

  • Una de las razones por las que <a href="https://seriesflixes.com">seriesflix</a> ha ganado tantos seguidores es su amplia variedad de contenido. Desde dramas emocionales hasta comedias relajantes, pasando por emocionantes series de crímenes y documentales informativos, hay algo para cada tipo de espectador.

  • Uma das características mais impressionantes do <a href="https://scarletiosapp.com">scarlet ios 2023</a> é sua interface de usuário revolucionária. O sistema operacional adota um design minimalista e elegante, focando na usabilidade e na fluidez da interação. A interface é projetada para se adaptar às preferências individuais do usuário, aprendendo com seus padrões de uso e ajustando-se automaticamente para fornecer uma experiência personalizada.

  • <a href="https://bigtorrhu.com/huntorrent-belepes/">huntorrent belépés</a> Ezek a platformok híresek a kizárólagos tartalmukról, szoros közösségeikről és a nyilvános torrent oldalakhoz képest nagyobb biztonságukról. Ebben a cikkben felfedezzük a Huntorrentot, annak jellemzőit, valamint a privát torrent követők használatának előnyeit és hátrányait.

  • You wrote it very well. I'm blown away by your thoughts. how do you do. I'm blown away by your thoughts. How do you do it, tell me, you are my inspiration.

  • Your explanation is organized very easy to understand!!! I understood at once. Could you please post about <a href="https://google.cf/url?sa=t&url=https%3A%2F%2Fwww.mtclean.blog/">majorsite</a> ?? Please!!

  • Of course, your article is good enough, <a href="https://google.cd/url?sa=t&url=https%3A%2F%2Fwww.mtclean.blog/">bitcoincasino</a> but I thought it would be much better to see professional photos and videos together. There are articles and photos on these topics on my homepage, so please visit and share your opinions.

  • When I read an article on this topic, <a href="https://google.cat/url?sa=t&url=https%3A%2F%2Fwww.mtclean.blog/">safetoto</a> the first thought was profound and difficult, and I wondered if others could understand.. My site has a discussion board for articles and photos similar to this topic. Could you please visit me when you have time to discuss this topic?

  • Your writing is perfect and complete. <a href="https://google.ca/url?sa=t&url=https%3A%2F%2Fwww.mtclean.blog/">casino online</a> However, I think it will be more wonderful if your post includes additional topics that I am thinking of. I have a lot of posts on my site similar to your topic. Would you like to visit once?

  • <a href="https://www.tech4era.com/" ref="dofollow">Tech4era</a>

  • Excellent post. I was checking constantly this blog and I’m impressed!Very helpful information specifically the last part Icare for such info a lot.

Add a Comment

As it will appear on the website

Not displayed

Your website