2013-04-02 251 views
0

我有一個Windows應用程序必須每秒完成一次20次的API調用。同步異步API調用

要求是讀取操作必須在幾毫秒內完成。

以下代碼使用每秒運行一次的計時器。 aaList是一個包含20個對象的列表。

不幸的是,由於我目前的代碼有些讀取是在不同的時間完成的(有時半秒鐘後),所以顯然在某個地方形成瓶頸。

任何人都可以建議如何我的要求可以實現在一個更同步的方式嗎? (也許我應該以不同的方式做這個?)

private void tmrAAProcess_Tick(object state) 
{ 

    foreach (aa in aaList) { 
      Task.Factory.StartNew(() => 
      {      
      aa.ReadFromWebsite(); 
      }, TaskCreationOptions.LongRunning); 

    } 

} 
+0

每秒恰好20次?這是每50毫秒,Windows不是一個實時操作系統,這是不可能的。 – Femaref

+0

那麼他們不會運行每50ms ... 20個電話將需要在同一時間每秒同時進行。 –

+0

我認爲你需要測量究竟花了多長時間。它是否啓動線程?或者實際上提出要求?是(一些)對同一臺服務器的請求?您是否嘗試過使用['Barrier'](http://msdn.microsoft.com/zh-cn/library/system.threading.barrier.aspx)來同步這些線程? – svick

回答

1

一個可能的問題是ServicePointManager默認只允許兩到同一站點的併發連接。你必須改變DefaultConnectionLimit財產,一個。

另一個問題是TPL將限制你的並行性。我不知道你的ReadFromWebsite方法是幹什麼的,但是如果它正在進行阻塞呼叫(即HttpWebRequest.GetResponse),那麼很可能你最終會遇到一堆排隊的任務。

我無法想象你會得到每個請求持續50毫秒的速率。只有通信時間可能會超過這個時間,除非它是一個內部服務器。一段時間後,您的計算機將無法使用連接,因爲它正在等待響應。無論是那個,還是你會用盡所有那些排隊的任務。

如果你想使這個工作,你必須至少:

  1. 修改ServicePointManager.DefaultConnectionLimit
  2. 進行異步Web請求
  3. 使用隊列明確限制併發未完成的請求數或信號量或類似的東西。

您應該保持最後N個(某些合理的小數字,如20個)請求的響應時間的平均運行時間,並且不會使請求更快。

+0

謝謝。你指出我正確的方向。 ReadFromWebsite()確實是同步的。我改變了它是異步的,所以我不需要打開一個新的線程。因此我能夠刪除Task.Factory.StartNew調用。我已經設置了defaultconnectionlimit。所以現在,由於沒有創建新線程,速度會更快。這不完全是同時發生的,但對我的需求來說已經足夠好了。 –