假設我有10個項目(我需要通過http協議獲取它們),代碼N中的任務開始獲取數據,每個任務依次需要10個項目。我把這些物品放在ConcurrentQueue<Item>
。之後,這些項目將逐個以線程不安全的方式處理。異步/等待任務和WaitHandle
async Task<Item> GetItemAsync()
{
//fetch one item from the internet
}
async Task DoWork()
{
var tasks = new List<Task>();
var items = new ConcurrentQueue<Item>();
var handles = new List<ManualResetEvent>();
for i 1 -> N
{
var handle = new ManualResetEvent(false);
handles.Add(handle);
tasks.Add(Task.Factory.StartNew(async delegate
{
for j 1 -> 10
{
var item = await GetItemAsync();
items.Enqueue(item);
}
handle.Set();
});
}
//begin to process the items when any handle is set
WaitHandle.WaitAny(handles);
while(true)
{
if (all handles are set && items collection is empty) //***
break;
//in another word: all tasks are really completed
while(items.TryDequeue(out item))
{
AThreadUnsafeMethod(item); //process items one by one
}
}
}
我不知道條件是否可以放在標記爲***
的語句中。我不能在這裏使用Task.IsCompleted
屬性,因爲我在任務中使用了await
,所以任務很快完成。而一個bool[]
表示任務執行到底是否看起來真的很難看,因爲我認爲ManualResetEvent可以做同樣的工作。任何人都可以給我一個建議嗎?
「阻塞當前線程,直到當前實例接收到信號」,這樣您將有10個阻塞線程等待信號。 – Sebastian
@Sebastian「備註:如果超時爲零,則該方法不會阻塞,它將測試等待句柄的狀態並立即返回。」 – jaggedSpire
@jaggedSpire好吧,這是我錯過的信息。謝謝,現在這是我首選的檢查WaitHandles的解決方案。 – Sebastian