Измерьте время запроса на сервере - PullRequest
2 голосов
/ 01 декабря 2009

Я хотел бы вычислить время, которое проходит между двумя конкретными моментами:

- start moment would be call to method IDispatchMessageInspector
.AfterReceiveRequest
- end moment would be call to method IDispatchMessageInspector.BeforeSendReply

На самом деле, я бы хотел вычислить время, необходимое для выполнения пользовательского кода вызова службы. Я думал, что эти два метода IDispatchMessageInspector - хорошее место для подключения. Но, к сожалению, я не знаю, как связать AfterReceiveRequest для сообщения с соответствующим вызовом BeforeSendReply.

Спасибо, Павел.

Ответы [ 2 ]

9 голосов
/ 01 декабря 2009

Вот инспектор параметров, который я однажды написал для измерения производительности моих методов службы 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
    }
}

Разница в том, что при использовании инспектора параметров не будет учитываться время, затрачиваемое на сериализацию параметров ввода / вывода. Это будет учитывать только время операции. Если вы хотите включить время сериализации, вы можете использовать IDispatchMessageInspector . Метод BeforeSendReply также имеет correlationState, который работает так же.


UPDATE:

Вы можете настроить инспектор параметров в 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)
    {
    }
}

И в вашем конфигурационном файле вы регистрируете расширение:

<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>
0 голосов
/ 01 декабря 2009

Как насчет этого?

public object AfterReceiveRequest(
    ref System.ServiceModel.Channels.Message request, 
    IClientChannel channel, InstanceContext instanceContext)
{
    return DateTime.Now;
}

public void BeforeSendReply(
    ref System.ServiceModel.Channels.Message reply, object correlationState)
{
    TimeSpan elapsed = DateTime.Now - ((DateTime)correlationState);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...