在多级产品中,经常会遇到某个环节响应时间极短的情况,如果该环节不能在几秒或几毫秒内响应请求,调用进程就会因为等待响应而超时。本文将介绍一套开源库,这套库能够帮助避免这类问题。
本文介绍的代码是开源的,遵循BSD许可证,并且可以在GitHub上找到。
可以通过NuGet将这些组件添加到解决方案中。对于服务器组件(想从中获取调试信息的代码):
Install-Package Ratcow.Debugging.Server
或者在Visual Studio的“包管理器”中搜索Ratcow.Debugging.Server。对于客户端(应该创建一个主机应用程序来查看数据):
Install-Package Ratcow.Debugging.Client
或者在Visual Studio的“包管理器”中搜索Ratcow.Debugging.Client。本文使用的是最新版本,客户端是0.0.1,服务器是0.0.2。但是接口非常简单,所以不太可能会有破坏性更改。
在应用程序中,必须注册一些实例以使它们可用,注册实例时,将提供一个或多个属性的名称。例如,给定这个类:
public class TestClassOuter {
public TestClassOuter() {
Value = new TestClass();
}
public TestClass Value { get; set; }
}
public class TestClass {
public string S { get; set; }
public int I { get; set; }
}
可以看到外部类TestClassOuter包含一个内部类的属性,而内部类TestClass有两个属性。这个例子展示了两种可能的注册方式。
可以这样做:
var c = new TestClass {
I = 10,
S = "hello"
};
var dbs = new DebugInterface();
dbs.RegisterProperties(c, "c", "I", "S");
也可以这样做:
var c = new TestOuterClass();
c.Value.I = 10;
c.Value.S = "hello";
var dbs = new DebugInterface();
dbs.RegisterProperties(c, "c", "Value");
此时,有一个有效的DebugInterface。可以将其注册到WCF接口并开始调试值。在应用程序中,这将非常相似。为此,向应用程序添加一个私有变量(或使用最喜欢的IoC容器)。这个实例必须在应用程序的整个生命周期中存在。
ServiceHost debugInterfaceService;
debugInterfaceService = Ratcow.Debugging.Server.DebugInterface.Start(dbs);
此时,应用程序现在将通过库中嵌入的WCF服务导出注册的属性,只要在app.config中添加了WCF配置。(这一步将在未来的版本中消失,这只是因为提前发布了库,以便在项目中使用它们。)
XML配置如下:
<system.serviceModel>
<services>
<!-- simple generic debug interface -->
<service behaviorConfiguration="DebugInterfaceBehave" name="Ratcow.Debugging.Server.DebugInterface">
<endpoint address="http://127.0.0.1:9001/DebugInterface" binding="basicHttpBinding" contract="Ratcow.Debugging.Server.IDebugInterface" />
<host>
<baseAddresses>
<add baseAddress="http://127.0.0.1:9001/DebugInterface" />
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="DebugInterfaceBehave">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
现在应用程序正在运行 - 验证服务是否激活。访问主机机器上的http://127.0.0.1:9001/DebugInterface。应该看到服务的概览。如果没有,可能需要查看防火墙访问权限,并且可能需要以管理员权限运行应用程序(只是为了起步)。可以在稍后更改应用程序的权限,以允许WCF服务运行 - 但是为了测试它是否成功运行,在这里需要走一些捷径。
客户端可以像想要的那样复杂。但是一个基本的客户端包含在GitHub仓库中,如下所示:
class Program {
static void Main(string[] args) {
var client = new DebugInterfaceClient("http://127.0.0.1:9001/DebugInterface");
var names = client.GetVariableNames();
foreach (var name in names) {
Console.Write(name);
var value = client.GetVariableValue(name);
Console.WriteLine($": {value}");
}
Console.WriteLine("\r\n----------------------");
Console.WriteLine("any key to exit");
Console.ReadLine();
}
}
重要的是:
真的,就是这样!!有一个变量的实时视图,调试器永远不会参与减慢/停止应用程序的进度。如此频繁地使用这种技术,以至于创建了这个相当通用的库,以使其他人可以使用相同的技术。
像所有的调试接口一样 - 可能会想要从生产构建中排除这段代码。
这个库仍在发展中,将在更多变化发生时更新本文。