¿ Has comprobado que tu aplicación no lance el compilador ( csc.exe ) en tiempo de ejecución ?

En un post anterior ya comentaba que en Windows Communication Foundation ( WCF ) no es oro todo lo que reluce y algunas cosas me hacen reafirmarme en mi opinión. Hace poco tuvimos un «problema» con WCF que me dejó bastante contrariado. A continuación intentaré explicar lo que pasó.


Haciendo unas pruebas de carga sobre la aplicación web que estamos desarrollando nos dimos cuenta de que el rendimiento de la aplicación era bastante malo, porque cada vez que hacíamos una petición al servidor se lanzaba el compilador, el proceso csc.exe. Lógicamente, el rendimiento era malísimo porque el proceso csc.exe se quedaba con gran parte de la CPU, lo que hacía que se procesasen muy pocas peticiones.


Pero..¿ Por qué se lanza el compilador ? ¿ Qué sentido tiene ? En una versión release no le veo sentido por ningún lado….pero sí, sí tiene sentido.Y el sentido está en que usamos comunicación wcf entre la consola web y la lógica de negocio y en que en muchos casos se usan DataSets.


Cuando el cliente WCF genera el proxy para llamar al servidor automáticamente se crean clases con el atributo XmlSerializer para poder llamar al servidor.


El cliente, en tiempo de ejecución, por cada tipo de datos que es serializable y que usa XmlSerializer genera y compila código para serializarlo, lo que puede provocar un decremento importante en el rendimiento de la aplicación….y de hecho, eso está provocando.


Por tanto, aunque a nosotros se nos ha manifestado por usar DataSets, podría darse siempre que se usen tipo serializables con XmlSerializer.


Pero todo tiene solución y se puede cambiar este comportamiento y así evitar que se lance el compilador. La herramienta svcutil nos pérmite mejorar el rendimiento de nuestra aplicación generando el código de serialización necesario para nuestros tipos serializables evitando que esta operación se haga en tiempo de ejecución.


La secuencia a seguir es la siguiente:




  • Compilar el proyecto que tiene las clases proxys, es decir, las clases XmlSerializer.


  • Utilizar la herramienta svcutil.exe para generar el código de serialización para los tipos contenidos dentro del binario. 



    • ( svcutil.exe /t:xmlSerializer  <assemblyPath>* )


  • Incluir el fichero cs generado dentro de un proyecto llamado [original assembly].XmlSerializer.dll.


  • Compilar el proyecto.


  • Incluir el nuevo binario generado en el mismo directorio que el assembly que contiene los proxys.

Y ya está, ya no se vuelve a volver a ver el proceso csc.exe.


Como he comentado antes, esta situación podría darse en otras situaciones que no tengan nada que ver con los proxys wcf. Para estas situaciones existe otra utilidad llamada sgen.exe, que permite obtener la misma funcionalidad que hemos comentado, con la salvedad de que sgen ya genera directamente el assembly necesario para la serialización y no sólo el código fuente.


Para finalizar, comentar que aunque sea una situación normal la que he comentado, me parece bastante absurdo que sea una comportamiento por defecto. Esto sí que sigo sin entenderlo….

Ibon Landa

bon Landa lleva más de 15 años dedicado al desarrollo de software. Durante este tiempo ha trabajado en diferentes empresas en las cuáles ha podido trabajar en diferentes entornos y tecnologías. Actualmente está focalizado principalmente en tareas de desarrollo, arquitectura, en las herramientas del ciclo de vida y en todo lo relacionado con la plataforma de Cloud Computing Microsoft Azure, área en el que ha sido reconocido como MVP. Participa de forma activa en la comunidad, escribiendo su blog, manteniendo un portal sobre Microsoft Azure y colaborando con Microsoft y grupos de usuarios en eventos de formación, talleres y giras de producto.

5 comentarios en “¿ Has comprobado que tu aplicación no lance el compilador ( csc.exe ) en tiempo de ejecución ?”

  1. Ibon, pensaba que había quedado claro el porque de este comportamiento. Este hecho se debe precisamente a optimización del Framework. Para no tener que regenerar la clase entre multiples uso de un tipo en serialización, la primera vez que se usa se compila al vuelo para a partir de este momento usar este y ahorrar costes de serializacion. Este es un comportamiento que tenemos desde la primera version de .NET 1.0…

    Saludos
    unai

  2. Yo no estoy diciendo que sea un bug, sólo que en el caso que comento yo provoca un decrémento total del rendimiento, ya que por cada petición que hago se lanza el compilador…El cliente wcf es una consola ASP.NET que ataca a la lógica de negocio por WCF. El usuario navega por las pantallas y por cada una de ella de va lanzando el proceso csc.exe de fondo.

    Microsoft tb comenta que este comportamiento podría provocar una perdida de rendimiento y de ahí la funcionalidad de svcutil que comento en el post.

  3. Tu problema no es de WCF, es de la forma que tienes de enviar los objetos entre el cliente y servidor, y la forma en que .net los serializa.
    Tu problema es un error típico en la serialización de objetos. Cada vez que recibes un objeto, creas una clase nueva. .Net utiliza reflection para crear la clase en función de los datos que le llegan. Y lo peor no es que lance el csc para compilarla, si no que cada vez que crea una nueva clase va consumiendo memoria que no se libera.

    La solución que propones en buena, utilizando svcutil. Aunque a mi me gusta más generarme las clases a mano y decirle yo como serializarlas.

Responder a unai Cancelar respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *