How can I trace a variable at runtime in C#?

2019-01-25 17:57发布

How can I track a variable's values as they change, at runtime, in C#? I'm interested in the same functionality that the debugger provides when I'm tracing a variable through execution steps, only that I need to call upon it from my code. Some sort of key-value observing, but for all kinds of variables(local, class, static, etc), not only properties. So, basically, receive a notification when a variable's value changes.

5条回答
太酷不给撩
2楼-- · 2019-01-25 18:20

You are working from the assumption that the debugger can track variable changes. It can't.

It is possible with unmanaged code, the processor has dedicated debug registers that allow setting data breakpoints. Up to three are provided. It generates a hardware interrupt when it sees a particular memory location getting written. This otherwise very useful feature isn't available in managed code however. The garbage collector is completely incompatible with it, it moves objects around, giving them another address.

The managed debugger does support a "when hit" condition on a breakpoint, allowing you to dump info to the output window. That however requires a breakpoint, it cannot be triggered by a change in variable value. It also really slows down code execution since the debugger actually enters a break state before executing the condition.

The obvious place to put such a breakpoint is in a property setter. Which is what you'll need to implement this feature in code. You can do anything you want in that setter, using the Trace class for example.

查看更多
走好不送
3楼-- · 2019-01-25 18:23

The managed debugger uses the ICorDebug COM API for pretty much everything. The part that you're interested is ICorDebugValue and its descendants. Note that a LOT of the debugging API requires that the process be not running (ie, have encountered a breakpoint) in order for the various inspections to happen. A high level overview of ICorDebug is here. The documentation on it is kinda sparse, but some Googling may help. Good luck.

查看更多
神经病院院长
4楼-- · 2019-01-25 18:23

As others mentioned a mechanism like that makes only sense when using properties. In .NET you can then make use of the INotifyPropertyChanged interface.

For a sample how to implement it see

How to: Implement the INotifyPropertyChanged Interface

The referenced article talks explicitly about Windows Forms, but you are not bound to that (the interface is actually declared in the System.ComponentModel namespace in System.dll). In fact, this interface is widely used for data binding scenarios, e.g. in WPF.

查看更多
乱世女痞
5楼-- · 2019-01-25 18:35

The only sensible way you could do that without the debugger would be: don't use a variable, but use a property, and (perhaps conditionally) add trace to the setter:

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

Obviously this cannot then be used for arbitrary fields/variables.

查看更多
别忘想泡老子
6楼-- · 2019-01-25 18:42

To add to what Marc said, if you want to do this for lots of properties and methods you might want to check out aspect oriented programming techniques, and libraries such as PostSharp.

http://www.sharpcrafters.com/postsharp

查看更多
登录 后发表回答