Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/297.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何知道异步调用何时真正开始?_C#_.net_Asynchronous - Fatal编程技术网

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

C# 如何知道异步调用何时真正开始?,c#,.net,asynchronous,C#,.net,Asynchronous,我希望能够测量执行异步方法所需的时间 当我同步调用该方法时,我运行下面的代码,并得到方法MyMethod所用的确切时间 for (int i = 0; i < 5000; i++) { stopWatches[i].Start(); webService.MyMethod(new Request()); stopWatches[i].Stop(); } void BeginTimedMyMethod(...) { //create delegate wit

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

当我同步调用该方法时,我运行下面的代码,并得到方法MyMethod所用的确切时间

for (int i = 0; i < 5000; i++) {
    stopWatches[i].Start();
    webService.MyMethod(new Request());
    stopWatches[i].Stop();
}
void BeginTimedMyMethod(...)
{
    //create delegate with StartMethod as target
    //Invoke StartMethod delegate
}

void StartTimedMethod(Request request)
{
    stopWatches[i].Start();
    webservice.MyMethod(request);
}
for(int i=0;i<5000;i++){
秒表[i].Start();
MyMethod(新请求());
秒表[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();
}
var callback=新操作(ar=>{
int i=(int)ar.AsyncState;
试一试{
var-response=webService.EndMyMethod(ar);
秒表[i].Stop();
}
}
对于(int i=0;i<5000;i++){
BeginMyMethod(new Request(),new AsyncCallback(callback),i);
秒表[i].Start();
}
问题是秒表不再测量执行请求所需的时间。它们测量从请求进入线程池队列到调用结束的时间。因此,我最终得到了一个秒表列表,时间呈线性上升

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

谢谢


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

您究竟想对度量值做些什么?实际上,您正在测量从请求完成某些工作到完成某些工作所花费的实际时间。这似乎是有意义的。在代码切换之前和之后,您都在测量实际请求延迟。

这听起来像是在尝试围绕mymethod类设置一个方面。最简单的方法是使用类似PostSharp的AOP框架。您可以按照

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

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

    public void OnMethodExit()
    {
        _watch.End();
        Debug.Print(_watch.Duration);
    }
}
void BeginTimedMyMethod(...)
{
    //create delegate with StartMethod as target
    //Invoke StartMethod delegate
}

void StartTimedMethod(Request request)
{
    stopWatches[i].Start();
    webservice.MyMethod(request);
}
然后在你的课堂上用你的方法

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

这将允许您将该方面绑定到方法,而无需修改该方法。但是,您仍然需要能够在那里重新编译代码。因此,即使该类只是一个外部服务的代理,您也应该可以执行此操作,因为您应该能够将该方面放置在代理调用的顶部。

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

for (int i = 0; i < 5000; i++) {
    stopWatches[i].Start();
    webService.MyMethod(new Request());
    stopWatches[i].Stop();
}
void BeginTimedMyMethod(...)
{
    //create delegate with StartMethod as target
    //Invoke StartMethod delegate
}

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

为什么不能更改MyMethod的实现?