locked
C# equivalent of “EXCEPTION_CONTINUE_EXECUTION” with exception filter RRS feed

  • Question

  • Hi all,

    Is it possible that using C# to do some exception handling with filter function and continue execution at the point where the exception occurred like C++ does?

    Thanks,

    Thursday, August 27, 2009 7:09 AM

All replies

  • No, exceptions are thrown and walk up the call stack to until some code catches the exception. If the exception is not caught at all, your application will exit with an Unhandled Exception failure. So, the only thing you can do is put a try catch around the code that you expect to throw exceptions and handle that exception (in other words, let the user know a bad thing happened, or fix the data and try again or something like that).


    Geert van Horrik - CatenaLogic
    Visit my blog: http://blog.catenalogic.com

    Looking for a way to deploy your updates to all your clients? Try Updater!
    Thursday, August 27, 2009 7:58 AM
  • Yes:

      try {
        //...
      }
      catch {
        //...
        throw;
      }

    Use a catch (SomeException) clause to filter.
    Hans Passant.
    Thursday, August 27, 2009 12:05 PM
  • But this doesn't allow him to continue where the exception occurred (such as the On Error Continue in VB). It allows him to continue on the first location he catches the exception.
    Geert van Horrik - CatenaLogic
    Visit my blog: http://blog.catenalogic.com

    Looking for a way to deploy your updates to all your clients? Try Updater!
    Thursday, August 27, 2009 12:22 PM
  • Oops, I read CONTINUE_SEARCH.  CONTINUE_EXECUTION will still unwind stack frames to the active __except that returned that value.  And execution resumes after that __except block.  Same as a plain catch in C#.

    Hans Passant.
    Thursday, August 27, 2009 12:40 PM
  • IL allows this via exception filters. See CLI partition I, section 12.4.2 for details. The MSDN ExceptionHandlingClauseOptions enumeration (http://msdn.microsoft.com/en-us/library/system.reflection.exceptionhandlingclauseoptions.aspx) gives a bit of insight into how this works.

    C#, however, does not expose this in the language.

           -Steve


    Programming blog: http://nitoprograms.blogspot.com/
      Including my TCP/IP .NET Sockets FAQ
    MSBuild user? Try out the DynamicExecute task in the MSBuild Extension Pack source; it's currently in Beta so get your comments in!
    Thursday, August 27, 2009 1:22 PM
  • Hi sdfsokdghok[fsdhgfdg,

     

    As far as I know,  CLR does not support resumption after a managed exception ,  CLR also does not provide a similar facility at the IL level . We can do exception filter, but we can’t continue to run at faulting instruction.  If you want to do exception filter, here is a CLR blog, which will give you more information about exception filter:

    http://blogs.msdn.com/clrteam/archive/2009/08/25/the-good-and-the-bad-of-exception-filters.aspx

     

    More information about exception:

    Exception filters and C#

    http://blogs.msdn.com/cbrumme/archive/2003/10/01/51524.aspx

     

     

     

    If you have further question, please let  me know.

     

     

    Have a nice day.

     

    Guang-Ming Bian - MSFT

    MSDN Subscriber Support in Forum

    If you have any feedback on our support, please contact msdnmg@microsoft.com


    Please remember to mark the replies as answers if they help and unmark them if they provide no help
    Friday, August 28, 2009 6:59 AM
  • I believe you are correct. I was thrown off by the mention of a "filter handler", which in Partition I, section 12.4.2.5, is stated to allow execution to be resumed at the location of the exception.

    However, in the other partitions, there is only the concept of a "filter block" which has an associated handler.

    Presumably, the "filter handler" was from an earlier revision and has been removed in the standardized design.

          -Steve
    Programming blog: http://nitoprograms.blogspot.com/
      Including my TCP/IP .NET Sockets FAQ
    MSBuild user? Try out the DynamicExecute task in the MSBuild Extension Pack source; it's currently in Beta so get your comments in!
    Friday, August 28, 2009 2:37 PM
  • Hi Steve,

     

    I found the article you mentioned. There is a statement like below:

     

    >> Execution cannot be resumed at the location of the exception, except with a filter handler.

     

    I guess you said about it. As far as I know, it is that filter handle can resume from catch statement, not fault instruction. Here is sample:

     

    Module Module1

     

        Function Foo() As Boolean

     

            Console.Write("3")

     

            Return False

     

        End Function

     

        Sub Main()

     

            Dim P As Boolean = True

     

            Try

     

                Try

     

                    Console.Write("1")

     

                    If (P) Then

     

                        Throw New ArgumentNullException()

     

                    End If

     

                    Console.Write("P was False!")

     

                Finally

     

                    Console.Write("2")

     

                End Try

     

            Catch ex As ArgumentNullException When Foo()

     

                Console.Write("4")

     

            Catch ex As ArgumentException

     

                Console.Write("5")

     

            End Try

     

            Console.Write("6")

     

            Console.Read()

     

        End Sub

     

     

    End Module

     

    The application will output 13256, Console.Write("P was False!") will never output. Since Foo return false, it catch ArgumentException and output 5. So from the sample above, the exception filter will resume for next catch statement, not for fault instruction. Since Steve mentioned IL, here I also output IL code, see below:

     

    .method public static void  Main() cil managed

    {

      .entrypoint

      .custom instance void [mscorlib]System.STAThreadAttribute::.ctor() = ( 01 00 00 00 )

      // Code size       125 (0x7d)

      .maxstack  3

      .locals init ([0] bool P,

               [1] class [mscorlib]System.ArgumentNullException ex,

               [2] bool VB$CG$t_bool$S0)

      IL_0000:  nop

      IL_0001:  ldc.i4.1

      IL_0002:  stloc.0

      IL_0003:  nop

      IL_0004:  nop

      .try

      {

        IL_0005:  ldstr      "1"

        IL_000a:  call       void [mscorlib]System.Console::Write(string)

        IL_000f:  nop

        IL_0010:  ldloc.0

        IL_0011:  stloc.2

        IL_0012:  ldloc.2

        IL_0013:  brfalse.s  IL_001b

        IL_0015:  newobj     instance void [mscorlib]System.ArgumentNullException::.ctor()

        IL_001a:  throw

        IL_001b:  nop

        IL_001c:  ldstr      "P was False!"

        IL_0021:  call       void [mscorlib]System.Console::Write(string)

        IL_0026:  nop

        IL_0027:  leave.s    IL_0036

      }  // end .try

      finally

      {

        IL_0029:  nop

        IL_002a:  ldstr      "2"

        IL_002f:  call       void [mscorlib]System.Console::Write(string)

        IL_0034:  nop

        IL_0035:  endfinally

      }  // end handler

      IL_0036:  nop

      IL_0037:  leave.s    IL_0069

      IL_0039:  isinst     [mscorlib]System.ArgumentNullException

      IL_003e:  dup

      IL_003f:  brtrue.s   IL_0045

      IL_0041:  pop

      IL_0042:  ldc.i4.0

      IL_0043:  br.s       IL_0054

      IL_0045:  dup

      IL_0046:  stloc.1

      IL_0047:  call       void [Microsoft.VisualBasic]Microsoft.VisualBasic.CompilerServices.ProjectData::SetProjectError(class [mscorlib]System.Exception)

      IL_004c:  call       bool VBCTest.Module1::Foo()

      IL_0051:  ldc.i4.0

      IL_0052:  cgt.un

      IL_0054:  endfilter

      IL_0056:  pop

      IL_0057:  ldstr      "4"

      IL_005c:  call       void [mscorlib]System.Console::Write(string)

      IL_0061:  nop

      IL_0062:  call       void [Microsoft.VisualBasic]Microsoft.VisualBasic.CompilerServices.ProjectData::ClearProjectError()

      IL_0067:  leave.s    IL_0069

      IL_0069:  nop

      .try IL_0004 to IL_0039 filter IL_0039 handler IL_0056 to IL_0069

      IL_006a:  ldstr      "6"

      IL_006f:  call       void [mscorlib]System.Console::Write(string)

      IL_0074:  nop

      IL_0075:  call       int32 [mscorlib]System.Console::Read()

      IL_007a:  pop

      IL_007b:  nop

      IL_007c:  ret

    } // end of method Module1::Main

     

    We can see the red line code, it use a filter, it never have a chance to go to following line code, so we can also conclude it can’t resume at fault instruction:

        IL_001c:  ldstr      "P was False!"

    IL_0021:  call       void [mscorlib]System.Console::Write(string)

     

     

    If you have further question, please let me know.

     

     

    Guang-Ming Bian - MSFT

    MSDN Subscriber Support in Forum

    If you have any feedback on our support, please contact msdnmg@microsoft.com


    Please remember to mark the replies as answers if they help and unmark them if they provide no help
    Monday, August 31, 2009 9:43 AM
  • Hi sdfsokdghok[fsdhgfdg,

    Did you solve the problem?



    Best regards,
    Guang-Ming Bian - MSFT
    Please remember to mark the replies as answers if they help and unmark them if they provide no help
    Tuesday, September 8, 2009 9:35 AM