none
pre-generated mycode.XMLSerializers.dll not being loaded in simple app RRS feed

  • Question

  • I have a simple console app built using VS2010 in 32-bit against .net 2.0 framework.  The code uses a webservice that is very large and had to be built with wsdl.exe to generate a .cs file and subsequently tweaked to support some .Net nuances.  That said, the service class .cs file itself has no problems.

    However, since this large .cs file is >8MB, the compiled .xmlserializers.dll library is also huge and takes forever to build, > 2 minutes.  So I have VS build it (Generate set to "on" in the properties) and yet .Net still regenerates a temporary version of the stupid thing every time the console app runs, even though the .xmlserializers.dll file is in the same folder as the console app.  I have read to "Where the Internet Ends" (thanks silverstein:) and cannot find ANY solution to this.  I have went ahead and signed the code (which also signs the dll as well) and that doesn't work.  Tried switching to 64bit, no dice.

    I cannot for the life of me get the pre-generated serializers dll to be used.  I attached to the Assembly CurrentDomain AssemblyResolve event just before the service is instantiated and kick the error to the console - which returns the following (even though the file, the token, the name, the language, the version, all the same as the main executable).

    Not found: test2.XmlSerializers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=XXXXXXXXXXXXXXX

    Something just refuses to look in the current folder maybe?

    BTW, I started this in Debugging and they said to come over here.

    Wednesday, April 10, 2013 11:04 PM

Answers

  • OMG, http://stackoverflow.com/questions/172095/slow-soaphttpclientprotocol-constructor

    After three weeks and much persistence on google, FINALLY SOLVED!!

    Posting a cut of that post JUST IN CASE it disappears for some reason:

    The following is ripped from this thread on the VMWare forums:

    Hi folks,

    We've found that sgen.exe does work. It'just that there is a couple of additional steps beyond pre-generating the serializer dll's that we missed in this thread. Here is the detailed instruction

    PROBLEM

    When using the VIM 2.0 SDK from .NET requires long time to instantiate the VimService class. (The VimService class is the proxy class generated by running 'wsdl.exe vim.wsdl vimService.wsdl')

    In other words, the following line of code:

    _service = new VimService();

    Could take about 50 seconds to execute.

    CAUSE

    Apparently, the .NET XmlSerializer uses the System.Xml.Serialization.* attributes annotating the proxy classes to generate serialization code in run time. When the proxy classes are many and large, as is the code in VimService.cs, the generation of the serialization code can take a long time.

    SOLUTION

    This is a known problem with how the Microsoft .NET serializer works.

    Here are some references that MSDN provides about solving this problem:

    http://msdn2.microsoft.com/en-us/library/bk3w6240.aspx http://msdn2.microsoft.com/en-us/library/system.xml.serialization.xmlserializerassemblyattribute.aspx

    Unfortunately, none of the above references describe the complete solution to the problem. Instead they focus on how to pre-generate the XML serialization code.

    The complete fix involves the following steps:

    1. Create an assembly (a DLL) with the pre-generated XML serializer code

    2. Remove all references to System.Xml.Serialization.* attributes from the proxy code (i.e. from the VimService.cs file)

    3. Annotate the main proxy class with the XmlSerializerAssemblyAttribute to point it to where the XML serializer assembly is.

    Skipping step 2 leads to only 20% improvement in the instantiation time for the VimService class. Skipping either step 1 or 3 leads to incorrect code. With all three steps 98% improvement is achieved.

    Here are step-by-step instructions:

    Before you begin, makes sure you are using .NET verison 2.0 tools. This solution will not work with version 1.1 of .NET because the sgen tool and the XmlSerializationAssemblyAttribute are only available in version 2.0 of .NET

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

      wsdl.exe vim.wsdl vimService.wsdl

      This will output the VimService.cs file in the current directory

    2. Compile VimService.cs into a library

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

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

      sgen /p VimService.dll

      This will output the VimService.XmlSerializers.dll in the current directory

    4. Go back to the VimService.cs file and remove all System.Xml.Serialization.* attributes. Because the code code is large, the best way to achieve that is by using some regular expression substitution tool. Be careful as you do this because not all attributes appear on a line by themselves. Some are in-lined as part of a method declaration.

      If you find this step difficult, here is a simplified way of doing it:

      Assuming you are writing C#, do a global replace on the following string:

      [System.Xml.Serialization.XmlIncludeAttribute

      and replace it with:

      // [System.Xml.Serialization.XmlIncludeAttribute

      This will get rid of the Xml.Serialization attributes that are the biggest culprits for the slowdown by commenting them out. If you are using some other .NET language, just modify the replaced string to be prefix-commented according to the syntax of that language. This simplified approach will get you most of the speedup that you can get. Removing the rest of the Xml.Serialization attributes only achieves an extra 0.2 sec speedup.

    5. Add the following attribute to the VimService class in VimService.cs:

      [System.Xml.Serialization.XmlSerializerAssemblyAttribute(AssemblyName = "VimService.XmlSerializers")]

      You should end up with something like this:

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

    6. Regenerate VimSerice.dll library by

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

    7. Now, from your application, you can add a reference to VimSerice.dll library.

    8. Run your application and verify that VimService object instanciation time is reduced.

    ADDITIONAL NOTES

    The sgen tool is a bit of a black box and its behavior varies depending on what you have in your Machine.config file. For example, by default it is supposed to ouptut optimized non-debug code, but that is not always the case. To get some visibility into the tool, use the /k flag in step 3, which will cause it to keep all its temporary generated files, including the source files and command line option files it generated.

    Even after the above fix the time it takes to instantiate the VimService class for the first time is not instantaneous (1.5 sec). Based on empirical observation, it appears that the majority of the remaining time is due to processing the SoapDocumentMethodAttribute attributes. At this point it is unclear how this time can be reduced. The pre-generated XmlSerializer assembly does not account for the SOAP-related attributes, so these attributes need to remain in the code. The good news is that only the first instantiation of the VimService class for that app takes long. So if the extra 1.5 seconds are a problem, one could try to do a dummy instantiation of this class at the beginning of the application as a means to improve user experience of login time.

    • Marked as answer by Wizardberry1 Tuesday, April 16, 2013 5:35 PM
    Tuesday, April 16, 2013 5:35 PM

All replies

  • Hi,

    Do you check these materials on using pre-generated XmlSerializers?

    #Using SGen

    http://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/d303cdf0-ef16-4c2d-b550-5ce1d7199155

    #Using Pre-generated XmlSerializers to Increase Performance

    http://msdn.microsoft.com/en-us/library/ee704594.aspx

    #Boost performance with Pre-generated XmlSerializers

    http://blogs.msdn.com/b/crm/archive/2009/02/02/boost-performance-with-pre-generated-xmlserializers.aspx

    Hope this helps.

    Best Regards.


    Haixia
    MSDN Community Support | Feedback to us
    Develop and promote your apps in Windows Store
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Friday, April 12, 2013 10:02 AM
    Moderator
  • I have tried to add a Using Microsoft.XmlSerialization.GeneratedAssembly and as well as direct reference to the pre-generated serializer dll, but my class doesn't exist as suggested it would be in the "Using SGEN" link you sent.  The class is defined in the service file as:

        public partial class AXLAPIService : System.Web.Services.Protocols.SoapHttpClientProtocol {

    and a constructor of the same name:

        public AXLAPIService(

    When I try to specify Microsoft.XML..............AXLAPIServiceSerializer, it errors out with type or namespace doesn't exist...

    I still think this is on the wrong track - I am actually getting an assembly not found error even though the assembly file is in the same folder as the executable.  I've also tried putting it in the GAC and system32 for posterity.


    Friday, April 12, 2013 5:32 PM
  • So, I made some progress.  The "not found" error that is being returned is actually benign because it is responding that it cannot find it in the GAC and then moves on to the current directory where it apparently does find it.  This has been confirmed with procmon.exe to examine file activity while my app is running.

    However, this leads me to the observation that the thing that is taking sooooo long to run is the dynamic generation of the CLASS file *.cs that is in the local temp folder in my profile (current user profile).  That .cs file is generated (and it is big >19MB for my particular app) and then deleted immediately.

    I'm somewhat new to the process of using a web service locally compiled/referenced - can someone tell me if I can avoid the .cs file from being created/used or is it something fundamentally dumb about how .net works in this programming scenario?

    Tuesday, April 16, 2013 3:17 PM
  • OMG, http://stackoverflow.com/questions/172095/slow-soaphttpclientprotocol-constructor

    After three weeks and much persistence on google, FINALLY SOLVED!!

    Posting a cut of that post JUST IN CASE it disappears for some reason:

    The following is ripped from this thread on the VMWare forums:

    Hi folks,

    We've found that sgen.exe does work. It'just that there is a couple of additional steps beyond pre-generating the serializer dll's that we missed in this thread. Here is the detailed instruction

    PROBLEM

    When using the VIM 2.0 SDK from .NET requires long time to instantiate the VimService class. (The VimService class is the proxy class generated by running 'wsdl.exe vim.wsdl vimService.wsdl')

    In other words, the following line of code:

    _service = new VimService();

    Could take about 50 seconds to execute.

    CAUSE

    Apparently, the .NET XmlSerializer uses the System.Xml.Serialization.* attributes annotating the proxy classes to generate serialization code in run time. When the proxy classes are many and large, as is the code in VimService.cs, the generation of the serialization code can take a long time.

    SOLUTION

    This is a known problem with how the Microsoft .NET serializer works.

    Here are some references that MSDN provides about solving this problem:

    http://msdn2.microsoft.com/en-us/library/bk3w6240.aspx http://msdn2.microsoft.com/en-us/library/system.xml.serialization.xmlserializerassemblyattribute.aspx

    Unfortunately, none of the above references describe the complete solution to the problem. Instead they focus on how to pre-generate the XML serialization code.

    The complete fix involves the following steps:

    1. Create an assembly (a DLL) with the pre-generated XML serializer code

    2. Remove all references to System.Xml.Serialization.* attributes from the proxy code (i.e. from the VimService.cs file)

    3. Annotate the main proxy class with the XmlSerializerAssemblyAttribute to point it to where the XML serializer assembly is.

    Skipping step 2 leads to only 20% improvement in the instantiation time for the VimService class. Skipping either step 1 or 3 leads to incorrect code. With all three steps 98% improvement is achieved.

    Here are step-by-step instructions:

    Before you begin, makes sure you are using .NET verison 2.0 tools. This solution will not work with version 1.1 of .NET because the sgen tool and the XmlSerializationAssemblyAttribute are only available in version 2.0 of .NET

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

      wsdl.exe vim.wsdl vimService.wsdl

      This will output the VimService.cs file in the current directory

    2. Compile VimService.cs into a library

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

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

      sgen /p VimService.dll

      This will output the VimService.XmlSerializers.dll in the current directory

    4. Go back to the VimService.cs file and remove all System.Xml.Serialization.* attributes. Because the code code is large, the best way to achieve that is by using some regular expression substitution tool. Be careful as you do this because not all attributes appear on a line by themselves. Some are in-lined as part of a method declaration.

      If you find this step difficult, here is a simplified way of doing it:

      Assuming you are writing C#, do a global replace on the following string:

      [System.Xml.Serialization.XmlIncludeAttribute

      and replace it with:

      // [System.Xml.Serialization.XmlIncludeAttribute

      This will get rid of the Xml.Serialization attributes that are the biggest culprits for the slowdown by commenting them out. If you are using some other .NET language, just modify the replaced string to be prefix-commented according to the syntax of that language. This simplified approach will get you most of the speedup that you can get. Removing the rest of the Xml.Serialization attributes only achieves an extra 0.2 sec speedup.

    5. Add the following attribute to the VimService class in VimService.cs:

      [System.Xml.Serialization.XmlSerializerAssemblyAttribute(AssemblyName = "VimService.XmlSerializers")]

      You should end up with something like this:

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

    6. Regenerate VimSerice.dll library by

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

    7. Now, from your application, you can add a reference to VimSerice.dll library.

    8. Run your application and verify that VimService object instanciation time is reduced.

    ADDITIONAL NOTES

    The sgen tool is a bit of a black box and its behavior varies depending on what you have in your Machine.config file. For example, by default it is supposed to ouptut optimized non-debug code, but that is not always the case. To get some visibility into the tool, use the /k flag in step 3, which will cause it to keep all its temporary generated files, including the source files and command line option files it generated.

    Even after the above fix the time it takes to instantiate the VimService class for the first time is not instantaneous (1.5 sec). Based on empirical observation, it appears that the majority of the remaining time is due to processing the SoapDocumentMethodAttribute attributes. At this point it is unclear how this time can be reduced. The pre-generated XmlSerializer assembly does not account for the SOAP-related attributes, so these attributes need to remain in the code. The good news is that only the first instantiation of the VimService class for that app takes long. So if the extra 1.5 seconds are a problem, one could try to do a dummy instantiation of this class at the beginning of the application as a means to improve user experience of login time.

    • Marked as answer by Wizardberry1 Tuesday, April 16, 2013 5:35 PM
    Tuesday, April 16, 2013 5:35 PM