测量服务器上的请求时间

dra*_*fly 2 wcf

我想计算两个特定时刻之间的时间:

- start moment would be call to method IDispatchMessageInspector
.AfterReceiveRequest
- end moment would be call to method IDispatchMessageInspector.BeforeSendReply
Run Code Online (Sandbox Code Playgroud)

实际上,我想计算执行服务调用用户代码所需的时间.我认为IDispatchMessageInspector的这两个方法是钩子的好地方.但遗憾的是,我不知道如何将AfterReceiveRequest与相应的BeforeSendReply调用关联起来.

谢谢帕维尔.

Dar*_*rov 9

这是我曾经编写的一个参数检查器,用于衡量我的WCF服务方法的性能.请注意,在方法中启动并返回秒表BeforeCall,允许您在AfterCall方法中将其作为correlationState参数检索:

public class PerformanceCountersInspector : IParameterInspector
{
    public object BeforeCall(string operationName, object[] inputs)
    {
        return Stopwatch.StartNew();
    }

    public void AfterCall(string operationName, object[] outputs, object returnValue, object correlationState)
    {
        var watch = (Stopwatch)correlationState;
        watch.Stop();
        var time = watch.ElapsedMilliseconds;
        // Do something with the result
    }
}
Run Code Online (Sandbox Code Playgroud)

这里的区别在于使用参数检查器不会考虑序列化输入/输出参数所花费的时间.它只会考虑操作时间.如果要包含序列化时间,可以使用IDispatchMessageInspector.该BeforeSendReply方法也有一个correlationState是工作原理相同.


更新:

您可以通过编写行为扩展来在web.config中配置参数检查器:

public class PerformanceCountersBehaviorExtension : BehaviorExtensionElement, IServiceBehavior
{
    public override Type BehaviorType
    {
        get { return typeof(PerformanceCountersBehaviorExtension); }
    }

    protected override object CreateBehavior()
    {
        return this;
    }

    void IServiceBehavior.AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters)
    {
    }

    void IServiceBehavior.ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
    {
        foreach (ChannelDispatcher channelDispatcher in serviceHostBase.ChannelDispatchers)
        {
            foreach (var endpoint in channelDispatcher.Endpoints)
            {
                foreach (var operation in endpoint.DispatchRuntime.Operations)
                {
                    var inspector = new PerformanceCountersInspector();
                    operation.ParameterInspectors.Add(inspector);
                }
            }
        }
    }

    void IServiceBehavior.Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
    {
    }
}
Run Code Online (Sandbox Code Playgroud)

在配置文件中注册扩展名:

<services>
  <service name="MyAssembly.MyService" behaviorConfiguration="returnFaults">
    <endpoint address="" binding="basicHttpBinding" contract="MyAssembly.IMyServiceContract"/>
    <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
  </service>
</services>
<behaviors>
  <serviceBehaviors>
    <behavior name="returnFaults">
      <serviceDebug includeExceptionDetailInFaults="true"/>
      <serviceMetadata httpGetEnabled="true"/>
      <perfCounters />
    </behavior>
  </serviceBehaviors>
</behaviors>
<extensions>
  <behaviorExtensions>
    <add name="perfCounters" type="MyAssembly.PerformanceCountersBehaviorExtension, MyAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
  </behaviorExtensions>
</extensions>
Run Code Online (Sandbox Code Playgroud)