Подтвердить что ты не робот

Недопустимое исключение дескриптора в Visual Studio 2015

Я обнаружил, что один из моих тестов, который проходит в VS2013, терпит неудачу в VS2015, тест вызывает службу, которая включает, среди прочего, вызов Console.Clear();

чтобы узнать, что происходит, я сделал простой unit test

   [TestMethod]
    public void ExampleTest()
    {
        Console.Clear();
    }

Этот тест проходит в visual studio 2013, но в 2015 году я получаю следующую ошибку:

Имя теста: ExampleTest Test FullName: solution.Common.Test.CacheManagerTest.ExampleTest Источник теста: C:\solution.Common.Test\CacheManagerTest.cs: строка 34 Результат теста: сбой Продолжительность теста: 0: 00: 00.3015003

Результат StackTrace: at System.IO.__ Error.WinIOError(Int32 errorCode, String maybeFullPath) в System.Console.GetBufferInfo(Boolean throwOnNoConsole, Boolean & успешно) в System.Console.Clear()
at sol.Common.Test.CacheManagerTest.ExampleTest() в C:\solution.Common.Test\CacheManagerTest.cs: строка 35 Сообщение результата:
Метод теста Alexandria.Common.Test.CacheManagerTest.ExampleTest бросил exception: System.IO.IOException: дескриптор недействителен.

Я понимаю, что это плохой дизайн для моего сервиса, если он не вызван консолью. Причина, по которой я задаю этот вопрос, - понять, почему это происходит в новой версии Visual Studio. Это предполагаемое поведение? Что изменилось?

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

Изменить: я вызываю Console.clear из следующей DLL

Microsoft\Framework.NETFramework\v4.5.1\mscorlib.dll

Изменить 2:

изображение свойств testproject в обеих визуальных студиях обе визуальные студии

4b9b3361

Ответ 1

Изменения в VS2015 довольно заметны, используйте Test > Debug > All Tests, чтобы получить представление. Вы можете видеть, что теперь у него новый тестовый хост-процесс, его имя TE.ProcessHost.Managed.exe, хранящееся в каталоге C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\CommonExtensions\Microsoft\TestWindow.

Предыдущие версии VS использовали другой хост vstest.executionengine.exe. Одним заметным изменением в новом тестовом хосте является то, что он больше не является программой консольного режима. Что-то вы можете увидеть, запустив Dumpbin.exe/headers на exe.

Еще один способ увидеть основную проблему - с Диспетчером задач. Обратите внимание, что запуск теста в старой версии VS приводит к добавлению процесса conhost.exe. Это процесс, которому принадлежит консольное окно для приложения в режиме консоли. Проблема, которую я видел ранее, заключается в том, что этот процесс имеет тенденцию к утечке, а не завершается, когда тест завершается. Добавляя все больше экземпляров conhost.exe, в какой-то момент, исследуя эту проблему, у меня было 12 из них. Предположительно, изменения в VS2015 предназначены для решения этой проблемы.

Технически вы можете настроить unit test с помощью файла .runsettings и использовать элемент <ForcedLegacyMode>, чтобы заставить старый процесс тестового хоста быть использованным. Это, однако, не влияет на результат этого теста, похоже, что они рассматривали это несколькими способами.

Чтобы получить достаточное количество угадываний, я рекомендую вам использовать файл connect.microsoft.com для отправки отчета об обратной связи. Вы можете процитировать этот Q + A для справки.


Между тем, вы можете рассмотреть обходной путь. Обратите внимание, что Console.Clear(), как правило, является создателем проблем, он также не работает при нормальном использовании, когда вывод приложения режима консоли перенаправляется. Очень легко сделать из командной строки с помощью оператора >. Какова конечная причина, по которой она терпит неудачу в unit test. Вы захотите сделать код упругим, чтобы он мог нормально работать как в производстве, так и в unit test. Вот так:

    if (!Console.IsOutputRedirected) Console.Clear();

Для этого требуется таргетинг .NET 4.5 или выше. Вы можете использовать код в этом сообщении SO, если вам нужно настроить таргетинг на более ранние версии.