2009-12-01 65 views
2

我想計算的時間在兩個特定時刻之間跨越:測量請求時間在服務器上

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

其實,我想計算被執行服務調用用戶代碼所需要的時間。我認爲IDispatchMessageInspector的這兩個方法是很好的地方。但不幸的是,我不知道如何將AfterReceiveRequest消息與相應的BeforeSendReply調用關聯起來。

謝謝帕維爾。

回答

8

這是我曾經寫過的一個參數檢查器,用於測量我的WCF服務方法的性能。請注意,一個Stopwatch啓動,並在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 
    } 
} 

這裏的不同之處在於使用參數檢查員將不考慮時間採取序列化輸入/輸出參數。它只會佔用手術時間。如果你想包含序列化時間,你可以使用IDispatchMessageInspectorBeforeSendReply方法也有一個correlationState,它的工作原理是一樣的。


UPDATE:

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> 

你可以通過編寫一個行爲擴展配置web.config中的參數檢查

+0

傑出的:)謝謝達林 – dragonfly 2009-12-01 11:35:24

0

這是怎麼回事?

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); 
} 
相關問題