C#如何在运行时转储所有变量和当前值

是否有任何内置或第三方库允许您在运行时简单地将所有变量转储到内存中? 我想要的是能够查看变量和当前值,类似于通过点击断点并将鼠标hover在变量上来查看它们,但实际上不必停止程序执行(即只是获取快照)。 如果它可以将它们转储到一个文件然后可以在程序中打开以获得一个很好的GUI界面来查看它们会很好,但是简单的文本文件转储就足够了。

我想不出以一种通用的方式做到这一点的简单方法。 可行的方法是以编程方式创建正在运行的进程的转储文件。 您可以使用P / Invoke对dbghelp.dll例程执行此操作,也可以生成cdb.exe进程以创建转储文件。 获得文件后,可以在调试器中打开它,以便以后使用带有cdb.exe / windbg.exe的SOS.dll进行分析,甚至可以编写调试器脚本来自动转储所需的数据。

我相信某种日志框架会帮助你做到这一点……

查看:

http://www.dotnetlogging.com/

在我的工作场所,我们使用log4net ,这对我们来说非常好。

那么为什么要将所有变量转储出来供以后分析呢? 您是否考虑过首先编写代码测试,以便减少对调试器的依赖,并为您自动测试检查值?

在过去,我使用了YourKit .Net分析器来分析.Net应用程序。

虽然我只使用它来亲自连接到正在运行的应用程序,但Snapshot文档确实声明他们有一个Profiler API ,可用于以编程方式转储快照以供以后查看。

代码明智,这看起来像下面这么简单:

Controller c = new Controller(); String snapshotPath = c.CaptureSnapshot(); 

我相信您可以在以后将快照文件加载到YourKit GUI中以查看它们。

如果像JetBrains dotTrace Performance和RedGates ANTS Performance Profiler这样的其他流行的配置文件有类似的编程API,我也不会感到惊讶,但我无法在他们的网站上快速找到明显的文档(我不想看他们的网络研讨会找到如果这个function存在!)

为此,您可以使用WMemoryProfiler

  • 获取所有appdomains中的所有对象作为对象数组
  • 创建自己进程的内存转储
  • 将特定对象序列化到光盘

要实现这一点,您当然需要Windbg,但WMemoryProfiler的Api是完全管理的,您基本上可以自行调试您的过程。 该库负责处理通常的调试器奇怪事项,因为它将Windbg包装在一个很好的可访问库中。

下面的代码确实将System.Threading.Thread对象的所有实例都放到了一个对象数组中。 这样,您就可以在运行时为自己的应用程序对象编写可视化工具。 另一个重载只会为您提供所有AppDomain中的所有对象。

 using (var debugger = new MdbEng()) { var dummy = new Thread(() => {}); dummy.Name = "Dummy Thread"; // Get all thread objects in all AppDomains var threads = debugger.GetObjects("System.Threading.Thread", true); foreach (Thread t in threads) { Console.WriteLine("Managed thread {0} has Name {1}", t.ManagedThreadId, t.Name); } GC.KeepAlive(dummy); } 

由于它是Windbg的包装器,您还可以动态创建内存转储,然后从进程中加载​​内存转储,以从转储中提取对象数据以进行可视化。 商业内存分析器(例如Scitech的MemoryProfiler)使用这种技术多年,但是当你有一个巨大的内存转储时它很慢,因为它们也使用Windbg作为转储分析器。

您可以尝试使用随最终版本的visual studio提供的Intellitrace工具。 这就是你所描述的 – 它记录你的应用程序中发生了什么,并允许你调试它而不执行程序,将鼠标hover在变量和所有其他调试窗口上以帮助你。

您可以使用PostSharp 。 我发现由于部署了环境应用程序,记录调试时间非常有用。 并检测/记录了很多东西。

但显然你需要指定你需要记录的所有变量。

在这里查看更多细节。