如何知道异步调用何时真正开始?

时间:2009-10-26 17:18:03

标签: c# .net asynchronous

我希望能够衡量执行异步方法所需的时间。

当我同步调用该方法时,我运行以下代码,我得到了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的实现。

3 个答案:

答案 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()
    { ...
    }
}

这将允许您将该方面与方法联系起来,而无需修改方法。但是,您仍然需要能够在那里重新编译代码。因此,即使该类只是您无法控制的外部服务的代理,这应该是可行的,因为您应该能够将该方面放在代理呼叫的顶部。

相关问题