2009-10-26 184 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() 
    { ... 
    } 
} 

這將允許你配合這方面的方法,而無需修改的方法。但是,您仍然需要能夠在那裏重新編譯代碼。所以這應該是可行的,即使這個類僅僅是一個你無法控制的外部服務的代理,因爲你應該能夠將該方面放在代理呼叫的頂部。

相關問題