我希望能够衡量执行异步方法所需的时间。
当我同步调用该方法时,我运行以下代码,我得到了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的实现。
答案 0 :(得分: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);
}
答案 1 :(得分:0)
您到底想要测量什么?您可以测量从请求完成某项工作到完成工作所需的实际时间。这似乎有道理。在代码切换之前和之后,您都在测量实际的请求延迟。
答案 2 :(得分: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()
{ ...
}
}
这将允许您将该方面与方法联系起来,而无需修改方法。但是,您仍然需要能够在那里重新编译代码。因此,即使该类只是您无法控制的外部服务的代理,这应该是可行的,因为您应该能够将该方面放在代理呼叫的顶部。