1

I read the book "CLR via C#" by Jeffrey Richter. In chapter 20, there is a code example demonstrating usage of Constrained Execution Regions (CERs):

private static void Demo2() {
 // Force the code in the finally to be eagerly prepared
 RuntimeHelpers.PrepareConstrainedRegions(); // System.Runtime.CompilerServices namespace
 try {
 Console.WriteLine("In try");
 }
 finally {
 // Type2’s static constructor is implicitly called in here
 Type2.M();
 }
}
public class Type2 {
 static Type2() {
 Console.WriteLine("Type2's static ctor called");
 }
 // Use this attribute defined in the System.Runtime.ConstrainedExecution namespace
 [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
 public static void M() { }
}

And the following text:

Now, when I run this version of the code, I get the following output.

Type2's static ctor called
In try

But when I run this code I get the following output no matter if I use CERs or not:

In try
Type2's static ctor called

So, Type2 constructor is getting called after try block (breaking the meaning of CERs usages, as I understand it).

What can be possible reason of this?

EDIT: I'm using .Net Core 3.1 and VS Enterprise 2019 Preview Version 16.6.0 Preview 3.0, my code is:

using System;
using System.Runtime.CompilerServices;
using System.Runtime.ConstrainedExecution;

public sealed class Program
{
    public static void Main()
    {
        Demo2();
    }
    private static void Demo2()
    {
        RuntimeHelpers.PrepareConstrainedRegions();
        try
        {
            Console.WriteLine("In try");
        }
        finally
        {
            Type2.M();
        }
    }
}
public class Type2
{
    static Type2()
    {
        Console.WriteLine("Type2's static ctor called");
    }
    [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
    public static void M() { }
}

By the way, Type2 class can be inside the Program, it does not change the output.

helgez
  • 157
  • 1
  • 7
  • Can you show the relavent, where you are calling the method – Vivek Nuna Jun 12 '20 at 11:15
  • FWIW, it works for my (.NET Fx 4.6.2, 4.7.2 and .NET Core 3.1). BTW, your code isn't compilable. It is missing the `using` directives. You might want to indicate which .NET version you are using. – Christian.K Jun 12 '20 at 14:37
  • I'm using .Net Core 3.1, as you did – helgez Jun 12 '20 at 14:48
  • 1
    @helgez,I test your code on.NET Core3.1, .NET Core3.0, .NET Core2.1, .NET Core2.0, PrepareConstrainedRegions() doesn’t work, and in .NET Core2.2, other errors occurred, but in .NET Framework4.7.2, .NET Framework4.6.1, PrepareConstrainedRegions() worked. I think it is the platform problem. You can try .net framework to test the code. – Jack J Jun Jun 16 '20 at 01:43

2 Answers2

1

(This is not the full answer to what is actually going on here, but it might help you)

Your problem is most likely that you run your process from within Visual Studio (using CTRL+F5). It is then launched via VsDebugConsole.exe, which then starts your process (also see this).

For whatever reason - that would need to be researched - it looks as if CERs are not honored when running in this way.

What you could do to validate, is attempt to run your program directly from the command prompt / console.

Christian.K
  • 47,778
  • 10
  • 99
  • 143
  • Yeah, I already tried to compile my code with csc.exe, and it worked as should be. However, in VS I'm selecting "Release", starting app without debugging (ctrl + f5), and (for some reason, even though I can't even debug by breakpoint and etc) it just does not show me normal behaviour. I think there should be some other setting/option in VS that would make this (and maybe something other?) work, but I don't know where to find it. P.S Setting from answer to linked post does not help. – helgez Jun 14 '20 at 09:41
1

Here is a quote from Microsoft's article about Constrained Execution Regions:

CER is only supported in .NET Framework. This article doesn't apply to .NET Core or .NET 5 and above.

walruz
  • 1,135
  • 1
  • 13
  • 33