Ответ 1
Из раздела this на форумах VMWare:
Привет, люди,
Мы обнаружили, что sgen.exe действительно работает. Это просто пара дополнительных шагов, помимо предварительного генерации dll serializer, которые мы пропустили в этом потоке. Вот подробная инструкция
ПРОБЛЕМА
При использовании VIM 2.0 SDK из .NET требуется длительное время для создания экземпляра класса VimService. (Класс VimService - это прокси-класс, созданный при запуске "wsdl.exe vim.wsdl vimService.wsdl" )
Другими словами, следующая строка кода:
_service = new VimService();
Может потребоваться около 50 секунд для выполнения.
ПРИЧИНА
По-видимому,.NET XmlSerializer
использует атрибуты System.Xml.Serialization.*
, аннотируя прокси-классы для генерации кода сериализации во время выполнения. Когда прокси-классы много и велики, как и код в VimService.cs, генерация кода сериализации может занять много времени.
Решение
Это известная проблема с тем, как работает сериализатор Microsoft.NET.
Вот некоторые ссылки, которые MSDN предоставляет для решения этой проблемы:
http://msdn2.microsoft.com/en-us/library/bk3w6240.aspx http://msdn2.microsoft.com/en-us/library/system.xml.serialization.xmlserializerassemblyattribute.aspx
К сожалению, ни одна из приведенных выше ссылок не описывает полное решение проблемы. Вместо этого они сосредоточены на том, как предварительно генерировать код сериализации XML.
Полное исправление включает следующие шаги:
-
Создайте сборку (DLL) с предварительно сгенерированным кодом XML-сериализатора
-
Удалите все ссылки на атрибуты System.Xml.Serialization. * из прокси-кода (т.е. из файла VimService.cs)
-
Аннотировать основной класс прокси с атрибутом XmlSerializerAssemblyAttribute, чтобы указать ему, где находится сборщик XML-сериализатора.
Шаг перехода 2 приводит к 20% -ному улучшению времени создания для класса VimService
. Пропуск любого шага 1 или 3 приводит к неправильному коду. При всех трех шагах достигнуто улучшение на 98%.
Ниже приведены пошаговые инструкции:
Прежде чем начать, убедитесь, что вы используете инструменты .NET verison 2.0. Это решение не будет работать с версией 1.1.NET, поскольку инструмент sgen и XmlSerializationAssemblyAttribute
доступны только в версии 2.0.NET.
-
Сгенерируйте файл VimService.cs из WSDL, используя wsdl.exe:
wsdl.exe vim.wsdl vimService.wsdl
Это приведет к выводу файла VimService.cs в текущем каталоге
-
Скомпилируйте VimService.cs в библиотеку
csc /t:library /out:VimService.dll VimService.cs
-
Используйте инструмент sgen для предварительной генерации и компиляции XML-сериализаторов:
sgen /p VimService.dll
Это приведет к выводу VimService.XmlSerializers.dll в текущем каталоге
-
Вернитесь к файлу VimService.cs и удалите все атрибуты
System.Xml.Serialization.*
. Поскольку кодовый код является большим, лучшим способом добиться этого является использование некоторого инструмента замещения регулярных выражений. Будьте осторожны, так как вы делаете это, потому что не все атрибуты появляются на отдельной строке. Некоторые из них выложены как часть декларации метода.Если вы обнаружите, что этот шаг затруднен, это упрощенный способ сделать это:
Предполагая, что вы пишете С#, выполните глобальную замену в следующей строке:
[System.Xml.Serialization.XmlIncludeAttribute
и замените его на:
// [System.Xml.Serialization.XmlIncludeAttribute
Это избавит вас от атрибутов
Xml.Serialization
, которые являются крупнейшими виновниками замедления, комментируя их. Если вы используете какой-либо другой язык .NET, просто измените замененную строку на префикс-комментарий в соответствии с синтаксисом этого языка. Этот упрощенный подход даст вам большую часть ускорения, которое вы можете получить. Удаление остальных атрибутов Xml.Serialization позволяет получить дополнительный ускорение на 0,2 секунды. -
Добавьте следующий атрибут в класс VimService в VimService.cs:
[System.Xml.Serialization.XmlSerializerAssemblyAttribute(AssemblyName = "VimService.XmlSerializers")]
У вас должно получиться что-то вроде этого:
// ... Some code here ... [System.Xml.Serialization.XmlSerializerAssemblyAttribute(AssemblyName = "VimService.XmlSerializers")] public partial class VimService : System.Web.Services.Protocols.SoapHttpClientProtocol { // ... More code here
-
Восстановить библиотеку VimSerice.dll с помощью
csc /t:library /out:VimService.dll VimService.cs
-
Теперь из вашего приложения вы можете добавить ссылку на библиотеку VimSerice.dll.
-
Запустите приложение и убедитесь, что время инициализации объекта VimService сокращено.
ДОПОЛНИТЕЛЬНЫЕ ПРИМЕЧАНИЯ
Инструмент sgen - это немного черный ящик, и его поведение зависит от того, что у вас есть в файле Machine.config. Например, по умолчанию предполагается использовать оптимизированный код без отладки, но это не всегда так. Чтобы получить видимость в инструменте, используйте флаг /k на шаге 3, который заставит его хранить все свои временные сгенерированные файлы, включая исходные файлы и файлы параметров командной строки, которые он сгенерировал.
Даже после вышеописанного исправления время, необходимое для создания экземпляра класса VimService в первый раз, не мгновенно (1,5 секунды). Основываясь на эмпирическом наблюдении, кажется, что большая часть оставшегося времени связана с обработкой атрибутов SoapDocumentMethodAttribute
. На данный момент неясно, как это время может быть уменьшено. Предварительно сгенерированная сборка XmlSerializer не учитывает атрибуты, связанные с SOAP, поэтому эти атрибуты должны оставаться в коде. Хорошей новостью является то, что только первое создание класса VimService для этого приложения занимает много времени. Поэтому, если дополнительные 1,5 секунды являются проблемой, можно попытаться создать фиктивный экземпляр этого класса в начале приложения в качестве средства улучшения пользовательского времени входа в систему.