如何知道异步调用何时开始?
问题描述:
我希望能够测量执行异步方法所花费的时间。如何知道异步调用何时开始?
当我同步调用方法时,我运行下面的代码,并获取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的实现。
答
创建一个方法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);
}
答
你究竟想要做什么测量?因为您正在测量从请求完成某项工作到完成时所需的实际时间。这似乎是有道理的。在代码切换之前和之后,您都在测量实际的请求延迟。
答
这听起来像你想要做的是围绕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()
{ ...
}
}
这将允许你配合这方面的方法,而无需修改的方法。但是,您仍然需要能够在那里重新编译代码。所以这应该是可行的,即使这个类仅仅是一个你无法控制的外部服务的代理,因为你应该能够将该方面放在代理呼叫的顶部。
为什么你不能改变MyMethod的实现? – 2009-10-26 17:23:38