Я написал код с большим количеством рекурсии, что занимает довольно много времени. Всякий раз, когда я «приостанавливаю» пробежку, чтобы посмотреть, что происходит, я получаю:
Cannot evaluate expression because the code of the current method is optimized.
Думаю, я понимаю, что это значит. Однако меня озадачивает то, что после того, как я нажимаю step, код больше не «оптимизирован», и я могу смотреть на свои переменные. Как это произошло? Как можно переключаться между оптимизированным и неоптимизированным кодом?
Я не верю, что выбранный ответ полезен. Когда у вас будет возможность, проверьте ответ, оставленный через несколько месяцев «Никто». Это поможет тем, кто хочет решить ваш исходный вопрос.
Я отлаживал в режиме Release (краснея). Ответ Ламара заставил меня проверить.





Вероятно, вы пытаетесь отладить свое приложение в режиме выпуска, а не в режиме отладки, или у вас включена оптимизация в настройках компиляции.
Когда код компилируется с оптимизацией, некоторые переменные отбрасываются, если они больше не используются в функции, поэтому вы получаете это сообщение. В режиме отладки с отключенной оптимизацией вы не должны получать эту ошибку.
Нет, я не пытаюсь отлаживать приложение, созданное в режиме выпуска.
"или у вас в настройках компиляции включена оптимизация" <- это тоже не так?
Правильно, оптимизаций тоже нет.
Другие ответы не помогли, кроме вашего !!
Отладчик использует FuncEval, чтобы вы могли «просматривать» переменные. FuncEval требует, чтобы потоки в управляемом коде останавливались в безопасной точке GarbageCollector. Ручная «приостановка» выполнения в среде IDE приводит к тому, что все потоки останавливаются как можно скорее. Ваш высоко рекурсивный код будет иметь тенденцию останавливаться в небезопасной точке. Следовательно, отладчик не может оценивать выражения.
Нажатие F10 переместит к следующей точке Funceval Safe и включит оценку функции.
Для получения дополнительной информации просмотрите правила FuncEval.
Я сам задавался вопросом об этом, было бы неплохо резюмировать основные моменты сообщения в блоге в вашем ответе.
Эта ссылка действительно интересная.
В этом блоге указано решение или просто объясняется проблема?
Это не ответ. Пожалуйста, не делайте ссылки (особенно на большие блоки информации, которые не дают четкого ответа на вопрос).
Кажется, это все еще принятый ответ, поэтому я обновил свой ответ.
Я считаю, что то, что вы видите, является результатом оптимизации - иногда переменная будет использоваться повторно, особенно те, которые созданы в стеке. Например, предположим, что у вас есть метод, использующий два (локальных) целых числа. Первое целое число объявляется в начале метода и используется исключительно как счетчик для цикла. Ваше второе целое число используется после завершения цикла и сохраняет результат вычисления, который позже записывается в файл. В этом случае оптимизатор МОЖЕТ решить повторно использовать ваше первое целое число, сохранив код, необходимый для второго целого числа. Когда вы пытаетесь посмотреть на второе целое число на ранней стадии, вы получаете сообщение о том, что спрашиваете «Невозможно оценить выражение». Хотя я не могу объяснить точные обстоятельства, оптимизатор может позже передать значение второго целого числа в отдельный элемент стека, в результате чего вы сможете получить доступ к значению из отладчика.
Пока строка Debug.Break () находится над стеком вызовов, вы не можете оценивать выражения. Это потому, что эта линия оптимизирована. Нажмите F10, чтобы перейти к следующей строке - допустимой строке кода - и часы будут работать.
Это ответ. Надеюсь, в конечном итоге он будет отмечен как таковой.
Вопрос был в том, «что это значит», а не в том, как это исправить.
Мои первые два предложения тоже отвечают на эту часть.
Друг друга из Microsoft прислал это: http://blogs.msdn.com/rmbyers/archive/2008/08/16/Func_2D00_eval-can-fail- while-stopped-in-a-non_2D00_optimized-managed-method-that-push-more-than-256- аргумент-байты-.aspx
Наиболее вероятная проблема заключается в том, что ваш стек вызовов оптимизируется из-за слишком большой сигнатуры вашего метода.
Была та же проблема, но ее удалось решить, отключив перехват исключений в отладчике. Щелкните [Отладка] [Исключения] и установите для исключений значение «Необработанные пользователем».
Обычно у меня это отключено, но иногда это может пригодиться. Мне просто нужно не забыть выключить его, когда я закончу.
Найдите вызов функции с множеством параметров и попробуйте уменьшить число, пока не вернется отладка.
Это сводило меня с ума. Я пробовал подключаться с помощью управляемого и собственного кода - ничего не вышло.
Это сработало для меня, и я наконец смог оценить все выражения:
У меня возникла эта проблема, когда я использовал VS 2010. Моя конфигурация решения была выбрана (Отладка). Я решил эту проблему, сняв флажок со свойства «Оптимизировать код» в свойствах проекта. Проект (щелкните правой кнопкой мыши) => Свойства => Сборка (вкладка) => снимите флажок Оптимизировать код
В моем случае у меня было 2 проекта в моем решении, и я выполнял проект, который не был проектом запуска. Когда я изменил его на запускаемый проект, отладка снова заработала.
Надеюсь, это кому-то поможет.
Оценка:
В .NET «оценка функции (funceval)» - это способность среды CLR вводить произвольный вызов, когда отлаживаемая программа где-то остановлена. Funceval берет на себя ответственность за выбранный поток отладчика для выполнения запрошенного метода. По завершении funceval запускает событие отладки. Технически CLR определила способы выдачи отладчиком функции funceval.
CLR позволяет запускать funceval только для тех потоков, которые находятся в безопасной точке GC (т.е. когда поток не будет блокировать GC) и точке Funceval Safe (FESafe) (т.е. где CLR действительно может захватить funceval.) Вместе. Таким образом, возможные сценарии для CLR, поток должен быть:
остановлен в управляемом коде (и в безопасной точке сборки мусора): это означает, что мы не можем выполнить функцию в машинном коде. Поскольку собственный код находится вне контроля CLR, он не может настроить funceval.
остановлен при 1-м шансе или необработанном управляемом исключении (и в безопасной точке GC): то есть во время исключения, чтобы проверить как можно больше, чтобы определить, почему это исключение произошло. (например, отладчик может попытаться оценить и увидеть свойство сообщения при возникновении исключения.)
В целом, общие способы остановки в управляемом коде включают остановку в точке останова, шаге, вызове Debugger.Break, перехват исключения или при запуске потока. Это помогает в оценке метода и выражений.
Возможные решения: Согласно оценке, если поток не находится в точках FESafe и GCSafe, CLR не сможет захватить поток, чтобы инициировать funceval. Как правило, следующее помогает убедиться, что funceval запускается, когда ожидалось:
Шаг 1:
Убедитесь, что вы не пытаетесь отлаживать сборку «Release». Релиз полностью оптимизирован и поэтому приведет к ошибке в обсуждении. Используя стандартную панель инструментов или диспетчер конфигураций, вы можете переключаться между отладкой и выпуском.
Шаг 2:
Если вы по-прежнему получаете сообщение об ошибке, возможно, для оптимизации задана опция отладки. Проверьте и снимите флажок со свойства «Оптимизировать код» в разделе «Свойства проекта»:
Щелкните правой кнопкой мыши проект Выберите вариант «Свойства» Перейдите на вкладку «Сборка». Снимите флажок «Оптимизировать код».
Шаг 3:
Если вы по-прежнему получаете сообщение об ошибке, возможно, режим отладочной информации неверен. Проверьте и установите его на «полный» в «Расширенных настройках сборки»:
Щелкните правой кнопкой мыши проект Выберите вариант «Свойства». Перейдите на вкладку «Сборка». Нажмите кнопку «Дополнительно». Установите для параметра «Информация об отладке» значение «Полный».
Шаг 4:
Если проблема не исчезла, попробуйте следующее:
Выполните «Очистку», а затем «Перестройку» файла решения. Во время отладки: Перейдите в окно модулей (VS Menu -> Debug -> Windows -> Modules) Найдите свою сборку в списке загруженных модулей. Убедитесь, что указанный путь к загруженной сборке соответствует вашим ожиданиям. Проверьте измененную метку времени файла, чтобы убедиться, что сборка действительно была перестроена. Проверить, оптимизирован ли загруженный модуль или нет
Заключение:
Это не ошибка, а информация, основанная на определенных настройках и разработанная с учетом того, как работает среда выполнения .NET.
в моем случае я был в режиме выпуска, те, которые я изменил, чтобы отладить, все сработало
Ниже сработало для меня, спасибо @Vin.
У меня возникла эта проблема, когда я использовал VS 2015. Мое решение: в конфигурации выбрано (Отладка). Я решил эту проблему, сняв флажок со свойства Optimize Code в свойствах проекта.
Project (right Click)=> Properties => Build (tab) => uncheck Optimize code
Убедитесь, что у вас нет чего-то подобного
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
в вашем AssemblyInfo
У меня была аналогичная проблема, и она была решена, когда я построил решение в режиме отладки и заменил файл pdb в пути выполнения.
Вы нашли способ решения этой проблемы?