[英]Pausing a Parallel.Foreach loop
我正在運行一個 parallel.foreach 循環來遍歷一個列表。 每個列表項都包含一個 api 的標識符,我在循環中訪問它。
我正在訪問的 api 每分鍾最多有 225 個請求,所以我想在 220 個項目后暫停執行循環,並在整整一分鍾后再次恢復它們。 我嘗試使用 Thread.sleep(numMilliSeconds),但它似乎為每個進入睡眠狀態或類似性質的東西啟動了一個新線程。
這大致是我現在正在使用的:
Parallel.ForEach(list, (currentItem) =>{
while(numRequestsLastMinute > 220 && DateTime.Now.Minute == lastDownloadTime.Minute)
{
var timeToPause = (60 - DateTime.Now.Second) * 1000;
Console.WriteLine("Thread pausing for" + timeToPause/100 + "seconds...");
Thread.Sleep(timeToPause);
Console.WriteLine("Thread resuming...");
}
if(DateTime.Now.Minute > lastDownloadTime.Minute)
{
lastDownloadTime = DateTime.Now;
numRequestsLastMinute = 0;
}
//send requests
}
顯然,Thread.Sleep 不是 go 的正確方法,但是我可以在 Parallel.Foreach 循環中使用類似的構造嗎?
我選擇了批處理解決方案。 感謝您的提示,@Algef Almocera
int maxPerMinute = 220
while (list.Count > 0)
{
_ = Parallel.ForEach(batch, (currentItem) =>
{
});
batch = list.Take(maxPerMinute);
list = list.Skip(maxPerMinute).ToList();
Console.WriteLine(numItemsDone + " items downloaded");
if (DateTime.Now.Minute == lastDownloadTime.Minute)
{
var timeToPause = (60 - DateTime.Now.Second) * 1000;
Console.WriteLine(DateTime.Now.ToLongTimeString() + ": Thread pausing for " + timeToPause / 1000 + "seconds...");
Thread.Sleep(timeToPause);
Console.WriteLine(DateTime.Now.ToLongTimeString() + ": Thread resuming...");
}
lastDownloadTime = DateTime.Now;
}//end while
如果達到每分鍾 220 個請求,您想要停止/暫停每個任務。 所以他們每個人都可以達到它。 所以每個人都應該檢查它。 如果發生這種情況,所有任務都應該等到有人釋放它們。
所以我會有一個隊列來記錄最后一次 (0...220) API 調用的時間戳。 和一個鎖 object 實例。
在任務內部 - 在一個永遠循環中(帶有取消中止條件):
--> 所以帶鎖的整個代碼可以放在一個方法中並從任務中調用
我是否理解正確,從 UTC 0.000 秒開始,您在任何 60 秒或每絕對分鍾內不應超過 225 個請求?
PS:我有一個類似的問題,但被鎖定在當地時區的一天 - 例如 Instagram 只允許在當地時區一天 24 小時內發布 100 張照片:所以從 22:00 到 02,00 下一個早上仍然可以發布200張照片。 如果這兩天都沒有其他人發布。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.