【发布时间】:2010-03-10 20:02:57
【问题描述】:
我有一个 WCF 服务正在运行。我将它托管在一个 win forms 应用程序中,我希望在表单上实时显示有关它的使用情况的各种统计信息。显然我不希望 WCF 服务中的任何代码收集统计信息或处理任何 GUI。
目前我正在努力在 WCF 服务中添加一些事件,这将允许表单添加侦听器,以便它可以生成其统计信息。这是实现我的目标的正确方法还是有更具体的 WCF 机制?
【问题讨论】:
我有一个 WCF 服务正在运行。我将它托管在一个 win forms 应用程序中,我希望在表单上实时显示有关它的使用情况的各种统计信息。显然我不希望 WCF 服务中的任何代码收集统计信息或处理任何 GUI。
目前我正在努力在 WCF 服务中添加一些事件,这将允许表单添加侦听器,以便它可以生成其统计信息。这是实现我的目标的正确方法还是有更具体的 WCF 机制?
【问题讨论】:
正如已经建议的那样,静态计数器或事件和侦听器在技术上可以解决问题,但如果您的目标是更通用的解决方案,则可以使用 依赖注入 (DI) 来实现。
首先,您需要一个在 WCF 服务和宿主应用程序之间共享的 Mediator。您可以从 WCF 服务向该 Mediator 写入消息,然后它可以将这些消息分发到主机中的适当处理程序。
您需要将调解器注入您的 WCF 服务。您可以通过使用自定义ServiceHost 来执行此操作,该IInstanceProvider 将自定义IInstanceProvider 分配给服务合同。在我的书第 7 章出版之前,我所知道的关于如何为 WCF 启用 构造函数注入 的最佳大纲是 this blog post,如果您记住 delegate is just an anonymous interface。
有了这些,考虑将统计记录器作为Decorator 实现到“真实”服务,因为这样可以让您更好地关注点分离。像这样的:
[ServiceContract]
public interface IMyService
{
[OperationContract]
Foo DoStuff(Bar bar);
}
public class StatisticsDecorator : IMyService
{
private readonly IMyService service;
private readonly IMediator mediator;
public StatisticsDecorator(IMyService service, IMediator mediator)
{
if(service == null)
{
throw new ArgumentNullException("service");
}
if(mediator == null)
{
throw new ArgumentNullException("mediator");
}
this.service = service;
this.mediator = mediator;
}
public Foo DoStuff(Bar bar)
{
this.mediator.SignalBeforeDoStuff();
var result = this.service.DoStuff(bar);
this.mediator.SignalAferDoStuff();
return result;
}
}
在运行时,您可以将 IMyService 的“真实”实现与共享的 Mediator 一起注入 StatisticsDecorator。
如果您使用 DI 容器,您也许可以使用它的拦截功能而不是手动滚动装饰器,但概念是一样的。
【讨论】:
“标准”方法是使用性能计数器,但如果您(曾经/仅)想要向托管进程报告,那就有点矫枉过正了。
你可以使用事件+监听器,我觉得很好。
或者使用简单的静态计数器和 Interlocked.Increment(),这将是最快的方法。
【讨论】:
WCF 还提供了开发自定义行为的能力,允许您检查和扩展服务方法调用的各个方面。例如,存在可定制的行为来检查方法参数、检查消息内容以及控制如何调用操作。 This MSDN 杂志文章很好地概述了自定义行为。
我不确定您的仪器需求是什么,所以我不能说这是否适合您想要做的事情。恕我直言,事件+听众也是一个可行的解决方案。也许即使是两者的某种组合也可能是您最好的选择。
【讨论】: