2010-05-26 13 views
5

¿Cómo puedo rastrear los valores de una variable a medida que cambian, en tiempo de ejecución, en C#? Me interesa la misma funcionalidad que proporciona el depurador cuando estoy rastreando una variable a través de los pasos de ejecución, solo que necesito invocarla desde mi código. Algún tipo de observación de valores-clave, pero para todo tipo de variables (locales, de clase, estáticas, etc.), no solo propiedades. Entonces, básicamente, recibe una notificación cuando cambia el valor de una variable.¿Cómo puedo rastrear una variable en tiempo de ejecución en C#?

+0

¿Por qué el depurador no es una opción? Para eso es exactamente. –

+0

@ 0xA3 Porque necesito acceder a esos valores desde mi aplicación, en tiempo de ejecución, solo cuando cambian. – luvieere

+0

¿Qué hay de escribir los valores de cambios de la variable en un archivo de registro simple. – Shivam

Respuesta

3

Está trabajando bajo la suposición de que el depurador puede rastrear los cambios de variables. No puede.

Es posible con un código no administrado, el procesador tiene registros de depuración dedicados que permiten establecer puntos de interrupción de datos. Se proporcionan hasta tres. Genera una interrupción de hardware cuando ve una determinada ubicación de memoria que se escribe. Sin embargo, esta característica de lo contrario muy útil no está disponible en el código administrado. El recolector de basura es completamente incompatible con él, mueve objetos, dándoles otra dirección.

El depurador administrado admite una condición "cuando se golpea" en un punto de interrupción, lo que le permite volcar información en la ventana de salida. Sin embargo, eso requiere un punto de interrupción, no puede ser desencadenado por un cambio en el valor de la variable. También realmente ralentiza la ejecución del código ya que el depurador realmente entra en un estado de interrupción antes de ejecutar la condición.

El lugar obvio para poner un punto de interrupción así es en un establecimiento de propiedades. Que es lo que necesitarás para implementar esta característica en el código. Puedes hacer lo que quieras en ese setter, usando la clase Trace por ejemplo.

+0

⁺¹ para la respuesta, sin embargo estoy un poco en desacuerdo con un punto de una gran ralentización de un punto de interrupción condicional simple. Como C# se convierte en un bytecode, la forma más adecuada para un depurador es simplemente crear e insertar un bytecode que imprima un valor en el lugar del valor. No veo una razón por la cual no podría hacerse de esta manera, y de ahí otra implementación de un punto de corte de depurador que llamaría un error de rendimiento. –

+2

No, C# se convierte en código de máquina, IL es solo un paso intermedio. Use Depurar> Windows> Desensamblar para verlo. Característica, no es un error. –

0

La única manera sensata que podría hacer que sin el depurador sería: no utilizar una variable, pero el uso de una propiedad, y (tal vez de forma condicional) añadir traza para el colocador:

private int myValue; 
public int MyValue { 
    get {return myValue;} 
    set { 
     SomeTraceMethod(myValue, value, ...); 
     myValue = value; 
    } 
} 

Obviamente, esto no se puede usar para arbitrariamente campos/variables.

+0

¿Cómo lo hace el depurador para variables arbitrarias? ¿No hay una biblioteca de depuración que pueda ayudarme a lograr el mismo nivel de seguimiento? – luvieere

3

Para agregar a lo que dijo Marc, si desea hacer esto para un montón de propiedades y métodos, es posible que desee comprobar técnicas de programación orientadas a aspectos, y bibliotecas como PostSharp.

http://www.sharpcrafters.com/postsharp

0

Como otros mencionan un mecanismo como que sólo tiene sentido cuando se utiliza propiedades. En .NET puede hacer uso de la interfaz INotifyPropertyChanged.

Para una muestra de cómo implementarlo ver

How to: Implement the INotifyPropertyChanged Interface

Las conversaciones artículo de referencia de forma explícita sobre las formas de Windows, pero no están obligados a que (la interfaz se declara en realidad en el espacio de nombres System.ComponentModel en System.dll). De hecho, esta interfaz se usa ampliamente para escenarios de enlace de datos, p. en WPF.

+0

Mencioné en la pregunta que estoy interesado en variables arbitrarias, no en propiedades. Sé sobre INotifyPropertyChanged, lo que no sé es cómo rastrear variables arbitrarias, como lo hace el depurador. – luvieere

1

El depurador administrado utiliza la API COM ICorDebug para casi todo. La parte que le interesa es ICorDebugValue y sus descendientes. Tenga en cuenta que MUCHA cantidad de la API de depuración requiere que el proceso no se ejecute (es decir, haya encontrado un punto de interrupción) para que ocurran las diversas inspecciones.Una descripción general de alto nivel de ICorDebug es here. La documentación es un poco escasa, pero algunos de Google pueden ayudar. Buena suerte.

Cuestiones relacionadas