2013-09-01 43 views
0

客户端调用方法我的网络WCF服务的“富()” - 和接收大字节数组作为响应:如何以编程方式跟踪响应持续时间?

public byte[] Foo() 
{ 
    return new byte[10000000]; 
} 

显然,当客户端读取所有数据,HTTP连接被关闭 - 如果我知道什么时候发生这种情况,我可以追踪“传播”的总持续时间。我知道跟踪等 - 但我需要以编程方式具有此数据,所以我可以将其显示给用户。我如何跟踪这个?

+0

你可以声明'Stopwatch'类变量并在通话之前启动并在通话结束后显示“stopwatch.Elapsed”。如果您使用线程或任务,访问主窗口以向用户显示统计信息有点困难,但这个想法保持不变。 –

+0

肯定 - 但你能否指定我应该打电话给stopwatch.Elapsed? – avs099

+0

执行[默认的WCF性能计数器](http://msdn.microsoft.com/en-us/library/vstudio/ms731055(v = vs.100).aspx)是否提供您所需要的? – rene

回答

-1

您可以使用秒表类,找出时间是指这个MSDN链接:

http://msdn.microsoft.com/en-us/library/system.diagnostics.stopwatch.elapsed.aspx

 Stopwatch stopWatch = new Stopwatch(); 
     stopWatch.Start(); 
     // your wcf functionalities 
     stopWatch.Stop(); 
     long duration = stopWatch.ElapsedMilliseconds; 
+0

'stopWatch.Elapsed'是一个'TimeSpan'属性,比普通的毫秒更容易操作。 –

+0

我的Foo()方法是从CLIENT调用的,我不会从我的代码中调用它。 – avs099

+0

@ avs099是的,Foo()会被客户端调用,但是使用秒表,你可以计算你的wcf服务执行你的功能的总持续时间,然后你可以发送该持续时间给客户端或显示它,但是你想要的,我的意思是在您的SERVICE代码中。 –

0

我有两个解决方案,peformance计数器和一个自定义行为,但我不知道他们完全回答你的问题,因为我不考虑网络延迟。

性能计数器
第一soltuion使用内置performance counters其中接近您的要求。 基本上,您希望为您的服务启用performanceCounters,然后在您的服务中获取其中的一个。确切的持续时间不可用,但Calls per second是其他计数器。

确保将其添加到您的服务配置:

<system.serviceModel> 
    <diagnostics performanceCounters="All" /> 
</system.serviceModel> 

在你的服务有握着你的PerformanceCounter静态类。在我的示例中,我将静态实例添加到服务中,实际上我会将其移至另一个类。

public class Service1 : IService1 
{ 
    // in an ideal world thisd how instancename would look like 
    //[email protected] endpoint listener address 

    private static PerformanceCounter pc = new PerformanceCounter(); 

    // our static constructor 
    static Service1() 
    { 
     // naming of the instance is garbeld due to length restrictions... 
     var cat = new PerformanceCounterCategory("ServiceModelOperation 4.0.0.0"); 
     foreach (var instance in cat.GetInstanceNames()) 
     { 
      Trace.WriteLine(instance); // determine the instancename and copy over :-) 
     } 
     pc.CategoryName = "ServiceModelOperation 4.0.0.0"; 
     pc.CounterName = "Calls Per Second"; 
     pc.InstanceName = "[email protected]:||LOCALHOST:2806|SERVICE1.SVC"; 

    } 

    public CompositeType GetDataUsingDataContract(CompositeType composite) 
    { 
     // do interesting stuff here 

     // here I have the value (in the service call but you can call this from anywhere, 
     // even from another thread. 
     // or use perfmon.exe to obtain or make a graph of the value over time... 
     Trace.WriteLine(pc.NextValue().ToString()); 

     return composite; 
    } 
} 

定制行为
这种定制行为拦截servicemethod的调用和,使启动和停止计时器,并将结果的可能性。

添加以下类:

// custom self timing for any wcf operation 
    public class Timing :Attribute, IOperationBehavior, IOperationInvoker 
    { 
     IOperationInvoker innerOperationInvoker; 
     private string operName = ""; 

     public Timing() 
     { 
     } 

     public Timing(IOperationInvoker innerOperationInvoker, string name) 
     { 
      this.innerOperationInvoker = innerOperationInvoker; 
      operName = name; 
     } 

     public void ApplyDispatchBehavior(OperationDescription operationDescription, DispatchOperation dispatchOperation) 
     { 
      dispatchOperation.Invoker = new Timing(dispatchOperation.Invoker, operationDescription.Name); 
     } 

     public object Invoke(object instance, object[] inputs, out object[] outputs) 
     { 
      object value; 

      var sw = new Stopwatch(); 
      sw.Start(); 
      value = innerOperationInvoker.Invoke(instance, inputs, out outputs); 
      sw.Stop(); 
      // do what you need with the value... 
      Trace.WriteLine(String.Format("{0}: {1} ms", operName, sw.ElapsedMilliseconds)); 
      return value; 
     } 


     // boring required interface stuff 

     public object[] AllocateInputs() 
     { 
      return innerOperationInvoker.AllocateInputs(); 
     } 

     public IAsyncResult InvokeBegin(object instance, object[] inputs, AsyncCallback callback, object state) 
     { 
      return innerOperationInvoker.InvokeBegin(instance, inputs, callback, state); 
     } 

     public object InvokeEnd(object instance, out object[] outputs, IAsyncResult result) 
     { 
      return innerOperationInvoker.InvokeEnd(instance, out outputs, result); 
     } 

     public bool IsSynchronous 
     { 
      get { return innerOperationInvoker.IsSynchronous; } 
     } 

     public void AddBindingParameters(OperationDescription operationDescription, System.ServiceModel.Channels.BindingParameterCollection bindingParameters) 
     { 
      // throw new NotImplementedException(); 
     } 

     public void ApplyClientBehavior(OperationDescription operationDescription, ClientOperation clientOperation) 
     { 
      // throw new NotImplementedException(); 
     } 

     public void Validate(OperationDescription operationDescription) 
     { 
      // throw new NotImplementedException(); 
     } 
    } 

现在装点在你的界面,您希望将自己的时序存储与时序属性的操作:

[ServiceContract] 
public interface IService1 
{ 
    [OperationContract] 
    [Timing] // Timing for this Operation! 
    CompositeType GetDataUsingDataContract(CompositeType composite); 
} 
相关问题