2009-10-26 185 views
2

我希望能够测量执行异步方法所花费的时间。如何知道异步调用何时开始?

当我同步调用方法时,我运行下面的代码,并获取MyMethod方法所花费的确切时间。

for (int i = 0; i < 5000; i++) { 
    stopWatches[i].Start(); 
    webService.MyMethod(new Request()); 
    stopWatches[i].Stop(); 
} 

我改变了我的代码以异步执行MyMethod,所以现在我的代码看起来像这样。

var callback = new Action<IAsyncResult>(ar => { 
    int i = (int)ar.AsyncState; 

    try { 
     var response = webService.EndMyMethod(ar); 
     stopWatches[i].Stop(); 
    } 
} 

for (int i = 0; i < 5000; i++) { 
    webService.BeginMyMethod(new Request(), new AsyncCallback(callback), i); 
    stopWatches[i].Start(); 
} 

问题是秒表不再测量执行请求所需的时间。它们测量从请求输入到ThreadPool队列中直到调用结束的时间。所以我最终列出了一个秒表,时间线性上升。

如何修复我的秒表?有没有办法确切地知道请求何时开始?

谢谢!

更新:我无法更改MyMethod的实现。

+1

为什么你不能改变MyMethod的实现? – 2009-10-26 17:23:38

回答

1

创建一个方法BeginTimedMyMethod,不在webservice类中。在BeginTimedMyMethod的实现中,调用一个中间方法而不是异步调用的MyMethod。在那里启动秒表,然后拨打MyMethod。

void BeginTimedMyMethod(...) 
{ 
    //create delegate with StartMethod as target 
    //Invoke StartMethod delegate 
} 

void StartTimedMethod(Request request) 
{ 
    stopWatches[i].Start(); 
    webservice.MyMethod(request); 
} 
0

你究竟想要做什么测量?因为您正在测量从请求完成某项工作到完成时所需的实际时间。这似乎是有道理的。在代码切换之前和之后,您都在测量实际的请求延迟。

0

这听起来像你想要做的是围绕mymethod类设置一个方面。最简单的方法是使用PostSharp之类的AOP框架。您创建沿

public class MyStopWatchContext 
{ 
    Stopwatch _watch = new Stopwatch(); 

    public void OnMethodEntry() 
    { 
     _watch.Start(); 
    } 

    public void OnMethodExit() 
    { 
     _watch.End(); 
     Debug.Print(_watch.Duration); 
    } 
} 

然后线,你的方法你的东西类中你有

public class MyService 
{ 
    [MyStopWatchContext] 
    public void SomeServiceMethod() 
    { ... 
    } 
} 

这将允许你配合这方面的方法,而无需修改的方法。但是,您仍然需要能够在那里重新编译代码。所以这应该是可行的,即使这个类仅仅是一个你无法控制的外部服务的代理,因为你应该能够将该方面放在代理呼叫的顶部。

相关问题