2013-05-31 165 views
0

我在寫一個Windows Store應用程序,它將依賴於JSON api。 API的提供者要求每秒不超過1個API請求。每秒執行一次任務的最佳方式是什麼?

所以我創建了一個類,讓我來排隊的阻隔隊列中的請求,並在後臺線程它會運行一個循環,如下所示:

Loop 
{ 
// this will block until a request is added to the queue 
MyRequest = Queue.Take() 

// Create task to make the api request here. 

Thread.Sleep(1000) 
} 

通過這種方式,它會等待在嘗試將另一個請求出隊之前至少還有一秒。

我發現Thread.Sleep不適用於Windows應用商店。 Task.Delay()似乎不必要的浪費,因爲每次調用它時都會創建一個新任務。

我覺得可能有一種已知的方式來做到這一點,我不知道?

感謝,

+0

任務非常輕量級,在.NET 4.5/Core中更是如此。 –

回答

3

我知道Task.Delay()似乎很浪費,但我們建議由微軟員工和主持人的MSDN here

使用。睡眠()或無限循環一樣TGH建議將導致程序在等待時變得無反應。如果你想讓它在處理您的隊列響應,你會使用這樣的:

await Task.Delay(1000);

0

如果您希望任務在後臺執行,我會建議一個System.Threading.Timer。將其設置爲一次性而非週期性計時器,並在每次請求後進行刷新。例如:

System.Threading.Timer myTimer; 

// initialize timer 
myTimer = new Timer(TimerProc, null, 1000, Timeout.Infinite); 

void TimerProc(object state) 
{ 
    // do request here 
    // then reset the timer 
    myTimer.Change(1000, Timeout.Infinite); 
} 

這會在一個請求結束和下一個請求開始之間等待一秒鐘。

如果您希望滴答以一秒爲間隔執行,您必須確保它們不能重疊。這對Monitor來說很簡單。你需要的鎖定對象,並讓你的計時器的週期定時器:

object timerLock = new object(); 

// initialize periodic timer 
myTimer = new Timer(TimerProc, null, 1000, 1000); 

而且你的計時器PROC:

void TimerProc(object state) 
{ 
    if (!Monitor.TryEnter(timerLock)) 
    { 
     // a request is currently being processed 
     return; 
    } 
    try 
    { 
     // do request here 
    } 
    catch (expected exceptions) 
    { 
    } 
    Monitor.Exit(timerLock); 
} 

請注意,我沒有在finallyMonitor.Exit。有關原因,請參閱Eric Lippert的Locks and exceptions do not mix

相關問題