Я нашел странное поведение в VS2015 Вот подробности:
У меня есть проект .Net 4.6, ссылающийся на сборку 3.5. Эта сборка определяет в одном из них интерфейсы следующий метод, который я смог проверить с помощью декомпилятора Resharper.
void WriteString([MarshalAs(UnmanagedType.BStr), In] string data, [In] bool flushAndEND = true);
Обратите внимание на последний необязательный аргумент flushAndEND
, который имеет значение по умолчанию true
. Проблема теперь в том, что когда я использую этот метод в моем проекте, зависание над именем метода показывает обычный VS toolTip, который детализирует подпись метода, за исключением того, что для меня это показывает неправильное значение по умолчанию необязательного аргумента flushAndEND
. Вот скриншот
Чтобы все было еще хуже, я заметил, что во время выполнения при вызове метода WriteString
только с первым параметром flushAndEND
устанавливается значение false
, а не его значение по умолчанию, определенное в DLL. Я реферирование. Воздействие этого на наш проект было большим, потому что оно оказало большую особенность нашего приложения бесполезным и заблокировало большую часть наших регрессионных тестов.
Мне удалось преодолеть эту проблему, вынудив значение необязательного аргумента true при вызове метода, но я боюсь, что в проекте есть другие вызовы, которые страдают от одной и той же проблемы. Поэтому мне понадобится лучшее решение для этого или, по крайней мере, понять, в чем причина такого поведения.
Мы только что обновили нашу среду несколько недель назад. До того, как мы использовали VS2013, все работало нормально.
Я знаю подтвержденную .Net 4.6 ошибку, которая заставляет некоторые аргументы передавать неправильные значения, и я могу связать их с моей проблемой здесь, но, как говорится в статье, ошибка возникает только при компиляции для архитектуры x64. Мой проект - это приложение WPF, и мы скомпилируем его как x32.
Почему WriteString
вызывается с неправильным аргументом по умолчанию?
Я попытаюсь позже изолировать проблему в небольшом проекте и посмотреть, могу ли я воспроизвести проблему.
EDIT: мне удалось изолировать проблему и найти интересные вещи!
Я создал простое консольное приложение .Net 4.6, добавил ссылку на свою Dll и написал следующий простой код, который состоит из отправки команды на устройство и чтения ответа:
private static void Main(string[] args)
{
//Init managers
ResourceManager ioMgr = new ResourceManagerClass();
FormattedIO488 instrument = new FormattedIO488Class();
//Connect to the USB device
instrument.IO = (IMessage)ioMgr.Open("USB0::0x0957::0x0909::MY46312358::0::INSTR");
string cmd = "*IDN?";
//This is the problematic method from my dll
instrument.WriteString(cmd);
//Read the response
string responseString = instrument.ReadString();
Console.WriteLine(responseString);
Console.ReadKey();
}
Что я сделал дальше, открыт этот проект из VS 2013 и VS 2015. В обеих версиях VS я перестраивал проект и запускал его. Вот результаты:
VS2013: WriteString
вызывается с использованием значения CORRECT по умолчанию flushAndEND
(которое true
означает сброс буфера и завершение команды).
VS2015: WriteString
вызывается с использованием значения WRONG по умолчанию flushAndEND
, которое дало исключение тайм-аута.
Дальнейшие проверки между двумя версиями Visual Studio показывают, что средство просмотра браузера объектов в VS2013 показывает подпись метода как:
void WriteString(string data, [bool flushAndEND = True])
в то время как браузер объекта в VS2015 показывает подпись метода как:
void WriteString(string data, [bool flushAndEND = False])
Единственное объяснение этого поведения заключается в том, что проблема с компилятором VS2015 не считывает правильные значения по умолчанию из сборки.