2009-12-01 3 views
2

Je voudrais calculer le temps qui enjambe entre deux moments particuliers:Mesure du temps de demande sur le serveur

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

En fait, je voudrais calculer le temps nécessaire pour exécuter le code utilisateur d'appel de service. Je pensais que ces deux méthodes de IDispatchMessageInspector sont un bon endroit pour accrocher. Mais malheureusement, je ne sais pas comment associer AfterReceiveRequest pour un message avec l'appel BeforeSendReply correspondant.

Merci Pawel.

Répondre

8

Voici un inspecteur de paramètres que j'ai déjà écrit pour mesurer les performances de mes méthodes de service WCF. Notez qu'un Stopwatch est démarré et retourné dans la méthode BeforeCall qui vous permet de le récupérer dans la méthode AfterCall comme paramètre 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 
    } 
} 

La différence ici est que l'aide d'un inspecteur des paramètres ne prendra pas en compte le temps pris pour sérialiser les paramètres d'entrée/sortie. Cela ne prendra en compte que l'heure de fonctionnement. Si vous souhaitez inclure le temps de sérialisation, vous pouvez utiliser IDispatchMessageInspector. La méthode BeforeSendReply a également un correlationState qui fonctionne de la même manière.


MISE À JOUR:

Vous pouvez configurer l'inspecteur des paramètres dans web.config en écrivant une extension de comportement:

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) 
    { 
    } 
} 

Et dans votre fichier de configuration vous enregistrer l'extension:

<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

Exceptionnel :) Merci Darin – dragonfly

0

Que pensez-vous de cela?

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); 
} 
Questions connexes