我調用一個worker方法調用數據庫,然後迭代並返回並行處理的值。爲了防止它錘擊數據庫,我有一個Thread.Sleep在那裏暫停執行到數據庫。但是,這似乎阻止了Parallel.ForEach中仍在發生的執行。達到此目的的最佳方法是防止阻塞?Thread.Sleep阻止任務的並行執行
private void ProcessWorkItems()
{
_cancellation = new CancellationTokenSource();
_cancellation.Token.Register(() => WorkItemRepository.ResetAbandonedWorkItems());
Task.Factory.StartNew(() =>
Parallel.ForEach(GetWorkItems().AsParallel().WithDegreeOfParallelism(10), workItem =>
{
var x = ItemFactory(workItem);
x.doWork();
}), _cancellation.Token);
}
private IEnumerable<IAnalysisServiceWorkItem> GetWorkItems()
{
while (!_cancellation.IsCancellationRequested)
{
var workItems = WorkItemRepository.GetItemList(); //database call
workItems.ForEach(item =>
{
item.QueueWorkItem(WorkItemRepository);
});
foreach (var item in workItems)
{
yield return item;
}
if (workItems.Count == 0)
{
Thread.Sleep(30000); //sleep this thread for 30 seconds if no work items.
}
}
yield break;
}
編輯: 我改變了它包括的答案,它仍然沒有工作,我很期待。我將.AsParallel()。WithDegreeOfParallelism(10)添加到GetWorkItems()調用中。即使基線正在睡覺,我認爲並行應該繼續執行,我的期望是否不正確?
例如: 我有15個項目,它迭代並抓取10個項目並啓動它們。當每一個完成時,它會從GetWorkItems中請求另一個,直到它嘗試請求第16個項目。此時它應該停止嘗試抓取更多物品,但應該繼續處理物品11-15,直到這些物品完成爲止。這是平行應該如何工作?因爲它目前沒有這樣做。它目前正在做的是當它完成時6,它鎖定後續的10個仍在Parallel.ForEach中運行。
'Thread.Sleep'幾乎從來都不是一個好的解決方案。你能解釋一下你想要完成的事嗎? 'WorkItemRepository.GetItemList'做什麼? –
真正的程序不睡覺()。你正在浪費一個線程並令Task調度器感到沮喪。 –
@Jim Mischel:我很確定'WorkItemRepository.GetItemList'類似於'SELECT * FROM workqueue WHERE status ='unprocessed'',並將它們編譯爲可排隊的工作項類型thingy。 –