假设我有 10N 个项目(我需要通过 http 协议获取它们),在代码中启动 N 个任务来获取数据,每个任务依次获取 10 个项目。我把物品放在一个ConcurrentQueue<Item>
. 之后,这些项目以线程不安全的方法逐个处理。
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
}
}
}
我不知道 if 条件可以放在标记的语句中***
。我这里不能使用Task.IsCompleted
属性,因为我await
在任务中使用,所以任务很快就完成了。而一个bool[]
表示任务是否执行到最后的a看起来真的很难看,因为我认为ManualResetEvent可以做同样的工作。谁能给我一个建议?