Могу ли я остановить .NET 4, выполняющий устранение хвостового вызова?

Мы находимся в процессе миграции приложения на .NET 4.0 (с 3.5). Одна из проблем, с которой мы сталкиваемся, воспроизводима только при очень определенных условиях:

  • Только в сборке Release
  • Только с включенной оптимизацией и / или отладочной информацией, установленной на pdb-only.

Под этим я подразумеваю, если я отключу оптимизацию и установлю полную информацию об отладке, проблема исчезнет.

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

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

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

Изменить:

Я отследил проблему до следующего:

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

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:

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

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

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

13
задан jonnystoten 25 May 2011 в 15:07
поделиться