简体   繁体   中英

Why PrepareConstrainedRegions method does not work in c#?

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.

(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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM