Почему метод PrepareConstrainedRegions не работает в c #?

Я прочитал книгу Джеффри Рихтера «CLR через C #». В главе 20 приведен пример кода, демонстрирующий использование областей ограниченного выполнения (CER):

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

И следующий текст:

Теперь, когда я запускаю эту версию кода, я получаю следующий результат.

Type2's static ctor called
In try

Но когда я запускаю этот код, я получаю следующий результат независимо от того, использую я CER или нет:

In try
Type2's static ctor called

Итак, конструктор Type2 вызывается после try блока (что нарушает смысл использования CER, насколько я понимаю).

Что может быть причиной этого?

РЕДАКТИРОВАТЬ: Я использую .Net Core 3.1 и VS Enterprise 2019 Preview Version 16.6.0 Preview 3.0, мой код:

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

Кстати, класс Type2 может находиться внутри Program, это не меняет вывод.


person helgez    schedule 12.06.2020    source источник
comment
Можете ли вы показать релевант, где вы вызываете метод   -  person vivek nuna    schedule 12.06.2020
comment
FWIW, он работает для моих (.NET Fx 4.6.2, 4.7.2 и .NET Core 3.1). Кстати, ваш код не компилируется. Отсутствуют директивы using. Вы можете указать, какую версию .NET вы используете.   -  person Christian.K    schedule 12.06.2020
comment
Я использую .Net Core 3.1, как и вы   -  person helgez    schedule 12.06.2020
comment
@ helgez, я тестирую ваш код на .NET Core3.1, .NET Core3.0, .NET Core2.1, .NET Core2.0, PrepareConstrainedRegions () не работает, а в .NET Core2.2 другие ошибки произошло, но в .NET Framework4.7.2, .NET Framework4.6.1 PrepareConstrainedRegions () работал. Думаю, проблема в платформе. Вы можете попробовать .net framework для проверки кода.   -  person Jack J Jun - MSFT    schedule 16.06.2020


Ответы (2)


(Это не полный ответ на то, что на самом деле здесь происходит, но он может вам помочь)

Ваша проблема, скорее всего, в том, что вы запускаете свой процесс из Visual Studio (используя CTRL + F5). Затем он запускается через VsDebugConsole.exe, который затем запускает ваш процесс (также см. this).

По какой-то причине - это необходимо изучить - это выглядит так, как будто CER не учитываются при такой работе.

Что вы можете сделать для проверки, так это попытаться запустить вашу программу прямо из командной строки / консоли.

person Christian.K    schedule 14.06.2020
comment
Да, я уже пытался скомпилировать свой код с помощью csc.exe, и он работал как надо. Однако в VS я выбираю Release, запускаю приложение без отладки (ctrl + f5), и (по какой-то причине, хотя я даже не могу отлаживать по точке останова и т. Д.) Он просто не показывает мне нормального поведения. Я думаю, что в VS должны быть какие-то другие настройки / опции, которые заставили бы это (а может быть, что-то другое?) Работать, но я не знаю, где его найти. P.S Настройка из ответа на связанный пост не помогает. - person helgez; 14.06.2020