.NET Takes a Long Time to Instantiate the VimService Class
search cancel

.NET Takes a Long Time to Instantiate the VimService Class

book

Article ID: 343277

calendar_today

Updated On:

Products

VMware vCenter Server VMware vSphere ESXi

Issue/Introduction

Why does VMware Infrastructure SDK 2.0 from .NET take a long time to instantiate the VimService class?


Environment

VMware ESX Server 3.0.x
VMware Infrastructure SDK 2.0.x
VMware VirtualCenter 2.0.x
VMware ESX 4.0.x

Resolution

When you use the VMware Infrastructure SDK 2.0 from .NET, the VimService class takes a long time to instantiate. Essentially, the _service = new VimService(); statement can take as long as 50 seconds to execute. The following instructions allow you to address issues for Microsoft Visual Studio 2005 using .NET 2.0. You must upgrade your environment, if you have older versions such as Visual Studio 2003 or .NET 1.1.

Important: This patch will work only for the VI API 2.0.1 release.

The Problem

The Microsoft .NET XmlSerializer uses the System.Xml.Serialization.* attributes, which annotate the proxy classes, to generate serialization code in runtime. When the proxy classes are many and large, as is the case in the VimService.cs code, generating serialization code can take a long time.

This is a known problem with the Microsoft .NET serializer. The following MSDN links provide methods for solving this problem:

The above references do not describe the complete solution. They focus on how to pregenerate the XML serialization code.

Implementing the steps of this KB article will decrease the vimService instantiation call. Even after you have made the fix, the time to instantiate the VimService class for the first time is not instantaneous (1.5 seconds). Empirical observation shows that the majority of the time is due to processing the SoapDocumentMethodAttribute attributes. It is unclear how this time can be reduced. The pregenerated XmlSerializer assembly does not account for the SOAP-related attributes, so these attributes need to remain in the code. Fortunately, only the first instantiation of the VimService class for that application takes long. If the extra 1.5 seconds creates a problem, you can do a dummy instantiation of this class at the beginning of the application to improve the user's login time.

This KB describes two methods to address this problem. Alternative 1 provides a script that patches the generated stub files to work around the problem. Alternative 2 allows developers to implement the various steps on their own.

Alternative 1: Single Step Patch

A single step solution in the form of a patch that optimizes the C# stubs is available for SDK 2.0.1. This solution does not modify the samples subdirectories and backs up the files that are changed with a timestamp.

This patch file modifies the Build2005.cmd to use a script genvimstubs.cmd to patch the C# stubs and compile the generated stubs. genvimstubs.cmd uses a .NET utility OptimizeWsStubs.exe to patch the C# stubs. The patch file is available for SDK 2.0.1.

The updated Build2005.cmd file uses the genvimstubs.cmd script to:

  1. Comment references to XmlIncludeAttribute correctly.
  2. Add the XmlSerializerAssembly attribute.
  3. Build the VimService and associated Serializer DLLs.
  4. Rebuild the C# samples in the SDK.

Use the patched Build2005.cmd to regenerate the .NET Stubs that are optimized and improve startup time. genvimstubs.cmd and OptimizeWsStubs.exe allows you to generate stubs with your choice of namespaces and filenames.

Alternative 2: Step-by-Step Instructions

Do not perform this step if you have already run the new Build2005.cmd. The solution described below allows you to manually patch the generated stubs in VimService2005.dll by

  1. Creating a serializer assembly (a DLL) with the pre-generated XML serializer code. See Step 1, below.
  2. Removing all references to System.Xml.Serialization.XmlIncludeAttribute attributes from the proxy code (that is, from the VimService.cs file). See Step 2, below.
  3. Annotating the main proxy class with the XmlSerializerAssemblyAttribute to point it to the location of the XML serializer assembly. See Step 3, below.
  4. Regenerating the VimService2005.dll library. See Step 4, below.

Note: In the SDK C# samples, the DLL generated by default by Build2005.cmd for Visual Studio 2005 is named VimService2005.dll. If you want to avoid removing and re-adding DLL references, make sure you use VimService2005.dll where VimService.dll is used in the instructions below. You may also use any other DLL (or Assembly) name instead of VimService.dll, however, you must change the filename appropriately.

Step 1: Creating a Serializer Assembly (a DLL)

To create a serializer assembly:

  1. Generate the VimService.cs file from the WSDL, using wsdl.exe:

    wsdl.exe /n:<namespace> /out:<Stubfilename.cs> vim.wsdl vimService.wsdl

    This command outputs the VimService.cs file in the current directory. In order to generate stubs to a particular namespace being used in your application, use the /n:<yournamespace> parameter to wsdl.exe. For example, to generate to the VimApi namespace used by the SDK samples, the command line is:

    wsdl.exe /n:VimApi vim.wsdl vimService.wsdl

    By default, wsdl.exe will generate a file named VimService.cs. In order to generate a stub file named to your specifications, use the /out:<filename>.cs parameter to wsdl.exe. For example, to generate a file named VimObjects.cs similar to that in the SDK samples, the command line is:

    wsdl.exe /n:VimApi /out:VimObjects.cs vim.wsdl vimService.wsdl

  2. Compile VimService.cs into a library.

    csc /t:library /out:VimService2005.dll VimService.cs

  3. Use the sgen tool to pre-generate and compile the XML serializers.

    sgen /p VimService2005.dll

This command outputs the VimService2005.XmlSerializers.dll file in the current directory.

Step 2: Removing All System.Xml.Serialization.XmlIncludeAttribute attributes from the VimService.cs File

Refer to the MSDN documentation page for more details on this attribute:
http://msdn2.microsoft.com/en-us/library/system.xml.serialization.xmlincludeattribute.aspx</u>
To remove all System.Xml.Serialization.XmlIncludeAttribute attributes from the VimService.cs file:
  1. Use the "find and replace" capability in Visual Studio or your favorite editor.

    Find the following string in the stub C# file:

    [System.Xml.Serialization.XmlIncludeAttribute

    Replace it with:

    // [System.Xml.Serialization.XmlIncludeAttribute

    This will get rid of the XML.Serialization.XmlIncludeAttribute attributes that are the biggest culprits for the slowdown.

  2. If you are using some other .NET language, modify the replaced string to be prefix-commented according to the syntax of that language. This simplified approach gets you the largest speed improvement. Removing the rest of the Xml.Serialization attributes only achieves an additional 0.2 sec speed-up.

    A better mechanism is to use a regular expression based search and replace. For example, replace

    [System.Xml.Serialization.XmlIncludeAttribute(typeof(Foo))]

    with

    /* [System.Xml.Serialization.XmlIncludeAttribute(typeof(Foo))]*/

    This will ensure you have covered all cases, including methods.

Step 3: Adding a Serializer Assembly reference to the VimService Class

Add the following serializer assembly reference attribute to the VimService class in VimService.cs:
[System.Xml.Serialization.XmlSerializerAssemblyAttribute(AssemblyName = "VimService2005.XmlSerializers")]

You should end up with something like this:

// ... Some code here ...

[System.Xml.Serialization.XmlSerializerAssemblyAttribute(AssemblyName = "VimService2005.XmlSerializers")]
public partial class VimService : System.Web.Services.Protocols.SoapHttpClientProtocol {
// ... More code here.

The Assembly name should be the name of the Serializer DLL generated by the sgen tool.
Note: The behavior of the sgen tool varies depending on what you have in your Machine.config file. For example, by default the file is supposed to output optimized non-debug code, but that is not always the case. To get some visibility into the tool, use the /k flag, which causes the tool to keep all its temporary generated files, including the source files and command-line option files.

Step 4: Regenerating the VimService2005.dll Library

Regenerate the VimService2005.dll library with the following command:

csc /t:library /out:VimService2005.dll VimService.cs

Ensure your application references the new VimService2005.dll library.

Run your application and verify that the VimService object instantiation time is reduced.

Attachments

ATTpatch201.zip get_app