Могу ли я запретить .NET 4 выполнять устранение хвостовых вызовов?C#

Место общения программистов C#
Ответить
Anonymous
 Могу ли я запретить .NET 4 выполнять устранение хвостовых вызовов?

Сообщение Anonymous »

Мы находимся в процессе переноса приложения на .NET 4.0 (с версии 3.5). Одна из проблем, с которой мы сталкиваемся, воспроизводится только при очень специфических условиях:
  • Только в релизной сборке
  • Только если оптимизация включена и/или для отладочной информации установлено значение «только pdb».
Под этим я подразумеваю, если я отключу оптимизации и установите полную отладочную информацию, проблема исчезнет.

Рассмотренный код отлично работает на .NET 3.5 в режиме Release с оптимизация и т. д. включена, и это делается уже давно.

Я действительно не хочу предполагать, что в компиляторе C# есть ошибка, поэтому мой вопрос заключается в том, Есть ли какие-либо методы, которые я могу использовать для отслеживания того, что мы делаем неправильно, что приводит к неправильной оптимизации?

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

Изменить:

Я обнаружил проблему в следующем:

У нас есть этот код в конструкторе формы:

Код: Выделить всё

public ConnectionForm()
{
LocalControlUtil.Configure("ConnectionForm", "Username", usernameLabel);
LocalControlUtil.Configure("ConnectionForm", "Password", passwordLabel);
LocalControlUtil.Configure("ConnectionForm", "Domain", domainLabel);
LocalControlUtil.Configure("ConnectionForm", "Cancel", cancelButton);
LocalControlUtil.Configure("ConnectionForm", "OK", okButton);
}
Эти вызовы относятся к некоторому пользовательскому коду локализации. Конструктор этой формы вызывается из другой сборки. Метод LocalControlUtil.Configure вызывает метод Assembly.GetCallingAssembly(), который возвращает правильное значение для всех вышеперечисленных вызовов, кроме последнего.

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

Я предполагаю, что это JIT-инлайнинг последнего вызова метода в то место, где вызывался конструктор (в другой сборке). Добавление [MethodImpl(MethodImplOptions.NoInlining)] в конструктор выше решает проблему.

Кто-нибудь знает, почему это происходит? Мне кажется странным, что встроить можно только последнюю строку. Это новое поведение в .NET 4.0?

Изменить 2:

I сузили это до исключения хвостовых вызовов, я предполагаю, что это вызвано новыми возможностями хвостовых вызовов в .NET 4.

В приведенном выше коде последний вызов LocalControlUtil.Configure в конструкторе исключается и помещается в вызывающий метод, который находится в другой сборке. Поскольку метод вызывает Assembly.GetCallingAssembly, мы не получаем правильную сборку обратно.

Есть ли какой-нибудь способ остановить компилятор (или JIT или что бы это ни делало) от устранения хвостового вызова?

Подробнее здесь: https://stackoverflow.com/questions/570 ... limination
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»