Este artículo proviene de un motor de traducción automática.

Todo sobre CLR

Mejoras al diagnóstico de producción en CLR 4

Jon Langdon

En el equipo de Common Language Runtime (CLR), tenemos un grupo cuyo enfoque proporciona las API y servicios que permiten que otros usuarios puedan crear herramientas de diagnóstico para el código administrado. Los dos componentes principales poseemos (en términos de ingeniería dedicados de recursos) son la depuración administrado y las API de generación de perfiles (ICorDebug * y ICorProfiler *, respectivamente).

Al igual que el resto de los equipos de CLR y framework nuestro valor se pone de manifiesto sólo a través de las aplicaciones ha creado a partir de nuestras contribuciones. Por ejemplo, los equipos de Visual Studio consumen estos depuración y la API de generación de perfiles para sus herramientas de generación de perfiles de rendimiento y depurador administrado y un número de desarrolladores de terceros está generando herramientas con la API de generación de perfiles.

Durante los últimos 10 años, gran parte el enfoque en esta área de CLR y Visual Studio ha sido acerca de cómo habilitar escenarios de escritorio de desarrollador: ejecución paso a paso origen en un depurador para buscar errores de código; iniciar una aplicación con un generador de perfiles de rendimiento para ayudar a localizar con exactitud las rutas de acceso a código lento; editar y continuar para ayudar a reducir el tiempo empleado en el ciclo de generación de edición de depuración; y así sucesivamente. Estas herramientas pueden ser útiles para buscar errores en las aplicaciones después de ha sido instalados en el equipo del usuario o implementar en un servidor (ambos casos en lo sucesivo denominado producción), y tenemos un número de otros fabricantes crear herramientas de diagnóstico en la parte superior de nuestro trabajo de producción de nivel internacional.

Sin embargo, se obtienen constantemente comentarios de clientes y estos proveedores enfatiza la importancia de facilitando aún más buscar errores durante la vida útil de una aplicación. Después de todo, se suelen consideran errores de software para ser más costoso para corregir el posterior está encuentra en el ciclo de vida de la aplicación.

CLR 4 (el motor en tiempo de ejecución subyacente 4 de Microsoft .NET Framework) es la primera versión en el que hemos realizado un esfuerzo importante para abordar esos comentarios y comenzar a ampliar los escenarios nuestro soporte las API de diagnóstico al final de producción del espectro.

En este artículo, se eche un vistazo algunos de los escenarios que comprendemos para ser particularmente difícil en la actualidad, el enfoque que tomamos para resolver ellos y los tipos de herramientas permiten. Específicamente, explicaré cómo hemos evolucionamos la API de depuración para admitir la depuración de volcado para la aplicación-crash - escenarios se bloquea y cómo hemos facilitado detectar cuándo se bloquea es ocasionado por problemas de subprocesamiento múltiples.

Se también describen cómo agregar la capacidad de adjuntar herramientas de generación de perfiles a una aplicación que esté ejecutándose se aún más facilidad estos mismos escenarios de solución de problemas y reducir considerablemente el tiempo necesario para diagnosticar problemas causados por consumo de memoria excesiva.

Por último, brevemente explicaré cómo hemos facilitado las herramientas de generación de perfiles implementar quitando la dependencia en el registro. En todo, el foco está principalmente en los tipos de herramientas nuevos que permite a nuestro trabajo pero en su caso he incluido referencias a recursos adicionales que le ayudarán a comprender cómo puede beneficiarse de nuestro trabajo a través de Visual Studio.

Depuración de volcado

Volcado de depuración una característica popular que ofrecemos con Visual Studio 2010 es administrada. Volcados de proceso, suele hacer referencia simplemente como volcados, suelen utilizarse en escenarios para código nativo y administrado de depuración de producción. Un volcado es esencialmente una instantánea del estado de un proceso ’ un momento determinado. En concreto, su vuelca el contenido de memoria virtual del proceso (o algún subconjunto de los mismos) en un archivo.

Anteriores a Visual Studio de 2010, para depurar código administrado en volcados necesarios para utilizar el sos.dll de extensión de depurador de Windows especializados para analizar volcados, en lugar de herramientas más conocidas como Visual Studio (donde probablemente escribió y depurando el código durante el desarrollo del producto). Nuestro objetivo para la experiencia de alto nivel deseamos que tenga cuando se utiliza un volcado para diagnosticar problemas en Visual Studio es que viven depuración del estado detenido: ¿Qué observa al depurar el código y detenido en un punto de interrupción.

El punto más comunes en el tiempo para recopilar un volcado es cuando hay una excepción no controlada en una aplicación, un bloqueo. Utilice el volcado para averiguar por qué el bloqueo producido, normalmente inicial mirando en la pila de llamadas de subprocesos con errores. Otros escenarios donde se utilizan los volcados son problemas de uso de memoria y bloqueos de aplicaciones.

Por ejemplo, si su sitio Web ha dejado de procesar las solicitudes, podría adjuntar a un depurador, recopilar un volcado y reinicie la aplicación. Análisis sin conexión del volcado podrían mostrar, por ejemplo, que todos los subprocesos de procesamiento de solicitudes están esperando una conexión a la base de datos o quizás buscar un interbloqueo en el código. Problemas de uso de memoria pueden manifiesto de distintas maneras desde la perspectiva de un usuario final: la aplicación se ralentiza debido de recolección de elementos no utilizados excesivo; servicio se interrumpe debido a la aplicación se ha quedado sin memoria virtual y necesaria para reiniciarse; y así sucesivamente.

A través de 2 de CLR, las API de depuración proporcionan compatibilidad para depurar procesos de ejecución sólo, que dificultaba a herramientas como destino de los escenarios que se acaba de describir. Básicamente, no se diseñó la API con escenarios en mente de depuración de volcado. El hecho de que la API utiliza un subproceso auxiliar que se ejecutan en el proceso de destino a las solicitudes de servicio de depurador subraya este punto.

Por ejemplo, en CLR 2, cuando desea que un depurador administrado recorrer la pila del subproceso, envía una solicitud al subproceso auxiliar en el proceso que se está depurando. CLR en ese proceso de servicios de la solicitud y devuelve los resultados al depurador. Como un volcado es simplemente un archivo, no es ningún subproceso auxiliar para atender las solicitudes en este caso.

Para proporcionar una solución para depurar código administrado en un archivo de volcado, necesitábamos generar una API que no requieren una ejecución de código en el destino para inspeccionar el estado del código administrado. Todavía porque escritores (principalmente Visual Studio) del depurador ya dispone de una inversión significativa en el API para proporcionar depuración en proceso de depuración de CLR, nos no desee forzar el uso de dos API distintas.

Donde se desembarquen en CLR 4 era reimplementing un número de depurador API (principalmente las necesarias para la inspección de código y datos) para quitar el uso del subproceso auxiliar. El resultado es que la API existente ya no necesita cuidado si el destino es un archivo de volcado o un proceso directo. Además, los creadores de depurador son capaz de utilizar la misma API a ambos en vivo y escenarios de depuración de volcado de destino. Cuando live depuración específicamente para el control de ejecución, establecer puntos de interrupción y recorrer el código: la API de depuración todavía utiliza un subproceso auxiliar. A largo plazo, pretendemos quitar la dependencia para estos escenarios también. Rick Byers (un desarrollador anterior en los API de servicios de depuración) tiene una entrada de blog útil que describe este trabajo con más detalle en blogs.msdn.com/rmbyers/archive/2008/10/27/ICorDebug-RE-Architecture-in-CLR-4-0.aspx.

Ahora puede utilizar ICorDebug para inspeccionar el código administrado y datos en un archivo de volcado: recorrer las pilas, enumerar a las variables locales, obtener el tipo de excepción y así sucesivamente. Para los bloqueos y se bloquea, hay a menudo suficiente contexto disponible en las pilas de subprocesos and datos auxiliares para encontrar la causa del problema.

Aunque sabemos el diagnóstico de memoria y otros escenarios también son importantes, que simplemente no teníamos tiempo suficiente en la programación de CLR 4 para crear nuevas API que proporcionan a los depuradores de la capacidad de inspeccionar el montón administrado en la forma en que requiere este escenario. En el futuro, a medida que seguimos expandir los escenarios de diagnóstico de producción soportamos, espero que esto es algo que agregaremos. Más adelante en este artículo analizo otro trabajo que hemos hecho para ayudar a enfrentar ese escenario.

También me gustaría explícitamente destacar que este trabajo es compatible con destinos de 32 y 64 bits y tanto sólo administrado modo mixto (nativo y administrado) depuración y. Visual Studio 2010 proporciona mixto para volcados que contiene código administrado.

Inspección de bloqueo de Monitor

Programación multiproceso puede resultar difícil. Si explícitamente está escribiendo código multiproceso o aprovechar marcos o bibliotecas que están realizando para usted, puede ser bastante difícil diagnosticar problemas de código asincrónico y paralelo. Cuando tenga una unidad lógica de trabajo se ejecuta en un único subproceso, comprensión causalidad es mucho más sencillo y a menudo se puede determinar examinando simplemente la pila del subproceso llamada. Pero cuando ese trabajo se divide entre varios subprocesos, se convierte el flujo de seguimiento en mucho más difícil. ¿Por qué no está finalizando el trabajo? ¿Es alguna parte del mismo bloqueado en algo?

Con varios núcleos están convirtiendo en habituales, los programadores buscan más y más en paralelo como medio para la mejora del rendimiento de programación en lugar de simplemente confiar en los avances de la velocidad del chip. Los programadores de Microsoft se incluyen en este lote y en los últimos años nos hemos sido significativamente centrado en lo que facilita a los programadores tener éxito en esta área. Desde una perspectiva de diagnósticos, hemos agregado unas API sencillas pero útiles que activar las herramientas ayudar a los desarrolladores un mejor hacer frente a las complejidades del código multiproceso.

En el depurador CLR API hemos agregado inspección API para los bloqueos de monitor. En pocas palabras, monitores proporcionan una manera de programas sincronizar el acceso a un recurso compartido (algún objeto en su código .NET) a través de varios subprocesos. Por lo tanto, mientras un subproceso tiene el recurso bloqueado, otro subproceso espera. Cuando el subproceso propietario del bloqueo lo libere, el primer subproceso en espera ahora pueden adquirir el recurso.

En .NET Framework, los monitores se exponen directamente a través del espacio de nombres de System.Threading.Monitor, pero más habitualmente a través de las palabras clave de SyncLock en C# y Visual Basic y bloqueo respectivamente. También se utiliza en la implementación de métodos sincronizados, Task Parallel Library (TPL) y otros modelos de programación asincrónicas. El nuevo depurador API le permite comprender mejor qué objeto, si los hubiera, se bloquea un subproceso dado en y qué subproceso, si hay alguna, mantiene un bloqueo en un objeto determinado. Aprovechando estas API, depuradores pueden ayudar a los desarrolladores determinar con precisión los interbloqueos y entender cuando varios subprocesos combatir para un recurso (bloqueo composiciones) pueden estar afectando rendimiento de la aplicación.

Para obtener un ejemplo del tipo de herramientas permite este trabajo, desproteger paralelo las características de Visual Studio 2010 de depuración. Daniel Moth y Stephen Toub se ha proporcionado una descripción general excelente de éstos en el número de septiembre de 2009 de MSDN Magazine (MSDN.Microsoft.com/magazine/ee410778).

Una de las cosas nosotros más sobre el volcado de depuración de trabajo es que crear una vista resumida de destino de depuración significa nueva funcionalidad de inspección excites es agregada, como la característica de bloqueo de monitor de inspección, que proporciona el valor para ambos live y escenarios de depuración de volcado. Aunque espero que esta característica para ser extremadamente valioso para los desarrolladores mientras que inicialmente está desarrollando una aplicación, es el volcado de depuración de soporte que hacen que la inspección de bloqueo de monitor una incorporación atractiva a las características de diagnóstico de producción en CLR 4.

Tess Ferrandez, un ingeniero de soporte técnico de Microsoft, tiene un vídeo de Channel 9 (channel9.msdn.com/Posts/Glucose/Hanselminutes-on-9-Debugging-Crash-Dumps-with-Tess-Ferrandez-and-VS2010/) en el que ella simula un escenario de bloqueo convoy comunes a lo que ella ha encontrado al solucionar problemas de las aplicaciones del cliente. A continuación, ella le guiará a través de cómo utilizar Visual Studio 2010 para diagnosticar el problema. Es un excelente ejemplo de los tipos de situaciones que estas nuevas funciones permiten.

Más allá de volcados

Mientras que creemos que las herramientas de estas características permiten que ayudará a reducir la cantidad de tiempo que lleva a los desarrolladores resolver problemas en producción, we hacer no esperan (ni desea) volcado depuración el único medio para diagnosticar problemas de producción.

En el caso de diagnosticar problemas de los problemas de uso de una cantidad excesiva de memoria, normalmente, empezaremos con una lista de instancias de objetos agrupados por tipo con sus recuento y el tamaño de agregado y el progreso hacia la comprensión de las cadenas de referencia de objeto. Trayecto archivos de volcado que contienen esta información entre equipos de desarrollo, personal de operaciones de producción y los ingenieros de soporte técnico y los desarrolladores pueden ser lentos y difíciles de manejar. Y a medida que las aplicaciones crecen en tamaño, esto es especialmente frecuente con aplicaciones de 64 bits: los archivos de volcado también aumentan de tamaño y tardar más tiempo para desplazarse y procesar. Fue con estos escenarios de alto nivel en cuenta que se comprometió las características de generación de perfiles que se describen en las secciones siguientes.

Herramientas de generación de perfiles

Hay una serie de diferentes tipos de herramientas integradas en la parte superior de CLR de la generación de perfiles de API. Escenarios que implican la API de generación de perfiles generalmente se centran en tres categorías funcionales: rendimiento, memoria e instrumentación.

Rendimiento generadores de perfiles (como se muestra que se incluye en algunas de las versiones de Visual Studio) se centran en la que le indicará donde su código es dedicar tiempo. Los generadores de perfiles de memoria se centran en que detalla el consumo de memoria de la aplicación. Los generadores de perfiles de instrumentación hacer, bueno, todo lo demás.

Permítame clarificar un poco esa última instrucción. Una de las instalaciones de la API de generación de perfiles proporciona es la capacidad de insertar el lenguaje intermedio (IL) al código administrado en tiempo de ejecución. Llamamos a esta instrumentación del código. Los clientes utilizan esta funcionalidad para crear herramientas que ofrecen una amplia gama de escenarios de cobertura de código a la inyección de errores para la supervisión de producción de clase empresarial de aplicaciones basadas en .NET Framework.

Uno de los beneficios de que la API de generación de perfiles tiene sobre la API de depuración es que está diseñado para ser extremadamente ligera. Ambas son controladas por eventos API — por ejemplo, hay eventos en dos para la carga de ensamblados, crear subproceso, se inicia una excepción y así sucesivamente, pero con la API de generación de perfiles registre sólo para los eventos que le interesa. Además, se carga la DLL de generación de perfiles dentro del proceso de destino, garantizar un acceso rápido a tiempo de ejecución.

En cambio, el depurador API informa de cada evento a un depurador fuera de proceso cuando adjunta y suspende el motor en tiempo de ejecución en cada evento. Éstos son sólo un par de razones que la API de generación de perfiles es una opción atractiva para crear herramientas de diagnóstico en línea destinado a entornos de producción.

Generador de perfiles adjuntar y separar

Mientras va a crear herramientas en siempre, supervisión de aplicaciones de producción mediante instrumentación de IL varios proveedores, no tenemos muchas herramientas aprovechar las funciones de supervisión de rendimiento y memoria en la API de generación de perfiles para proporcionar compatibilidad con reactivos de diagnóstico. El principal impedimento en esta situación ha sido la incapacidad para adjuntar herramientas basadas en API a un proceso ya en ejecución de generación de perfiles de CLR.

En versiones anteriores CLR 4, el CLR comprueba durante el inicio para ver si se registró un generador de perfiles. Si encuentra un generador de perfiles registrado, el CLR lo carga y ofrece las devoluciones de llamada como se solicitó. Nunca se descarga el archivo DLL. Esto es generalmente fino si es de trabajo la herramienta generar una imagen de end-to-end del comportamiento de las aplicaciones, pero no funciona para problemas que no sabía existían cuando inicia la aplicación.

Quizás el ejemplo de esto más doloroso es el escenario de diagnóstico de uso de memoria. En la actualidad, en este escenario a menudo encontramos que el modelo de diagnósticos es recopilar varios volcados, observar las diferencias en tipos asignados entre cada uno, generar una escala de tiempo de crecimiento y, a continuación, buscar en el código de aplicación donde se hace referencia los tipos sospechosos. Quizás el problema es un mal había implementado esquema de almacenamiento en caché o quizá los controladores de eventos en un tipo se que mantengan referencias a otro tipo que es lo contrario fuera del ámbito. Los clientes y los ingenieros de soporte técnico de dedicar mucho tiempo diagnosticar estos tipos de problemas.

Para empezar, como brevemente mencioné anteriormente, volcados de procesos grandes son grandes a sí mismos y incitarles a un experto de diagnóstico pueden introducir grandes retrasos en el tiempo en resolución. Además, es el problema que tiene que implican a un experto, debido principalmente al hecho de que los datos sólo se exponen a través de una extensión de depurador de Windows. No hay ninguna API pública permite a las herramientas consumir los datos y generar vistas intuitivas en la parte superior o integrarlo con otras herramientas que podrían ayudar a análisis.

Para facilitar el inconveniente de este escenario (y algunos otros), hemos agregado una nueva API que permite a los generadores de perfiles adjuntar a un proceso en ejecución y aproveche un subconjunto de las API de generación de perfiles existentes. Permiten que están disponibles después de adjuntar el proceso de toma de muestras (consulte “ VS 2010: Asociar el generador de perfiles a una aplicación administrada ” en blogs.msdn.com/Profiler/Archive/2009/12/07/vs2010-Attaching-the-Profiler-to-a-Managed-Application.aspx) y diagnósticos de memoria: recorrido de pila; la asignación de función direcciones a nombres simbólicos; la mayoría de las devoluciones de llamada del recolector de elementos no utilizados (GC); y objeto de inspección.

En el escenario que acabo de describir, herramientas pueden aprovechar esta funcionalidad para permitir a los clientes adjuntar a una aplicación experimentando tiempos de respuesta lentos o el crecimiento de una cantidad excesiva de memoria, comprender actualmente lo que está ejecutando y saber qué tipos existan en el montón administrado y lo que es mantenerlos vivos. Después de recopilar la información, puede desasociar la herramienta y el CLR descargará el archivo DLL del generador de perfiles. Mientras que el resto del flujo de trabajo similar: búsqueda donde estos tipos se hace referencia o creados en el código, esperamos que herramientas de esta naturaleza tienen un impacto considerable en de la media de tiempo-resolución para estos problemas. Dave Broman, desarrollador en el CLR Perfilar API, explica esto y otras características de generación de perfiles en más profundidad en su blog (blogs.msdn.com/davbr).

Lo hace, no obstante, deseo llamar dos limitaciones explícitamente en este artículo. En primer lugar, adjunte el diagnóstico de memoria en está limitado a los modos de GC no simultánea (o bloqueo): Cuando el recolector de elementos no utilizados suspende la ejecución de todo el código administrado mientras realiza una recolección de elementos no utilizados. Aunque simultánea de catálogo global es el valor predeterminado, ASP.NET utiliza modo de servidor de catálogo global, que es un modo no simultánea. Éste es el entorno en la que vemos la mayoría de estos problemas. Valoramos la utilidad de adjuntar Perfilar diagnósticos para las aplicaciones cliente y espera ofrecer esto en una versión futura. Simplemente hemos prioridad en el caso más común, de 4 de CLR.

En segundo lugar, están no se puede utilizar la API de generación de perfiles para instrumentar IL después adjuntar. Esta funcionalidad es especialmente importante para nuestros proveedores de herramienta de supervisión empresarial que desean poder cambiar su instrumentación dinámicamente en respuesta a condiciones de tiempo de ejecución. Comúnmente conocemos esta característica como re JIT. En la actualidad, tendrá una oportunidad de cambiar el cuerpo de IL de un método: Cuando se está en primer lugar compilado JIT. Nos esperan entregar re-JIT para que sea una empresa significativa e importante y se están investigando activamente el valor para el cliente y implicaciones técnicas como consideramos que entrega el trabajo en una versión futura.

Activación sin registro para generadores de perfiles

Asociar generador de perfiles y el trabajo auxiliar de la habilitación de las API de generación de perfiles específicas después de adjuntar fue la mayor parte del trabajo que hicimos en el CLR API de generación de perfiles para CLR 4. Pero estábamos encantados encontrar otra característica muy pequeño (en términos de costo de ingeniería) tiene un impacto sorprendentemente grande en los clientes crear herramientas de la clase de producción.

Antes de 4 de CLR para una herramienta obtener su archivo DLL del generador de perfiles cargan en una aplicación administrada tenía que crear dos elementos claves de información de configuración. El primero era un par de variables de entorno que dijo el CLR para habilitar la generación de perfiles y qué implementación de generador de perfiles para cargar (su CLSID o ProgID) cuando se inicia el CLR. Dado que las DLL del generador de perfiles se implementan como servidores COM en el proceso (con CLR está el cliente), el segundo fragmento de datos de configuración no la información de registro de COM correspondiente almacenada en el registro. Esto básicamente dijo el motor en tiempo de ejecución, por medio de COM, dónde encontrar el archivo DLL en disco.

Durante la planeación de 4 de CLR, al tratar de comprender cómo nos ha podido facilitar a los proveedores para crear herramientas de clase producción hemos tenido algunos interesantes conversaciones con algunos de nuestros proveedores de herramientas y los ingenieros de soporte. Los comentarios que recibimos fue que, cuando se enfrenta a un fallo en la aplicación en el entorno de producción, los clientes a menudo cuidado menor impacto a la aplicación (ya está fallando; simplemente desean obtener la información de diagnóstico y mover en) y más información acerca del impacto en el estado del equipo. Muchos clientes vaya a grandes longitudes para documentar y vigilar la configuración de sus equipos y introducir cambios en esa configuración, puede introducir riesgos.

Por lo tanto, con respecto a la parte de CLR de la solución, queríamos hacen posible para habilitar diagnósticos que se pueden implementar xcopy herramientas tanto a minimizar el riesgo de los cambios de estado y a reducir el tiempo necesario para obtener las herramientas de y en ejecución en el equipo.

En CLR 4 eliminamos la necesidad de registrar el generador de perfiles de COM DLL en el registro. Todavía necesitamos las variables de entorno si desea iniciar la aplicación bajo el generador de perfiles, pero no en los escenarios de adjuntar detallados anteriormente, no hay es necesario realizar ninguna configuración. Simplemente llama a la nueva asociación de API, pasadas de herramientas A la ruta de acceso a la DLL y el CLR carga el generador de perfiles. En el futuro, buscamos en formas de simplificar aún más la configuración del generador de perfiles ya que los clientes aún encontrar la solución de variable de entorno desafiante en algunos escenarios.

Combinados, habilitar las dos características de generación de perfiles que acabamos de analizar una clase de herramientas de Low overhead que los clientes puedan, en el caso de fallos inesperados implementar rápidamente a un equipo de producción para recopilar información de diagnóstico de memoria para ayudar a señalar la causa del problema o rendimiento. A continuación, simplemente lo más rápidamente, el usuario puede devolver el equipo a su estado original.

Conclusión

El trabajo sobre las características de diagnóstico para el CLR es bittersweet. Se ve muchos ejemplos de cuánto a los clientes tienen dificultades con ciertos problemas y aún hay siempre trabajo interesante que podemos hacer para ayudar a desarrollo de facilidad y hacer que los clientes más satisfechos. Si no está cambiando esa lista de problemas de un desafío de nuestros clientes: es decir, no estamos quitar elementos de un lo —, a continuación, no nos estamos realizando correctamente.

En el CLR 4 creo que creamos características que no sólo ofrecen valor inmediato de direccionamiento algunos problemas de cliente superior, sino también sentar las bases en el que podemos seguir generación en el futuro. En el futuro, continuaremos invirtiendo en las API y servicios que facilitan incluso exponer información de diagnóstico significativa en todas las fases de vida de la aplicación para poder centrarse más tiempo en la creación de nuevas características para sus clientes y menos tiempo a depurar los existentes.

Si está interesado en nosotros proporcionar comentarios nos estamos considerando para la próxima versión de trabajo de diagnósticos, nos hemos registrado una encuesta en surveymonkey.com/s/Developer-Productivity-Survey. Como ahora somos sobre buque 4 CLR, nos estamos centrándose gran parte de nuestro tiempo en próximas versiones planear y datos de la encuesta nos ayudarán priorizar nuestros esfuerzos por. Si tiene unos minutos, nos encantaría conocer su opinión.

Jon Langdon  es un administrador de programas en el equipo de CLR donde principalmente se dedica a diagnósticos. Antes de unirse al equipo de CLR, fue un consultor con los servicios de Microsoft, ayudando a los clientes a diagnosticar y corregir problemas con aplicaciones empresariales a gran escala.

Gracias al siguiente técnico experto para revisar este artículo: Rick Byers