gpt4 book ai didi

c# - 异步/等待任务和 WaitHandle

转载 作者:太空狗 更新时间:2023-10-29 23:24:54 26 4
gpt4 key购买 nike

假设我有 10N 个项目(我需要通过 http 协议(protocol)获取它们),在代码中启动了 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
}
}
}

我不知道如果条件可以放在标记为 *** 的语句中会怎样? .我不能使用 Task.IsCompleted这里的属性,因为我使用 await在任务中,所以任务很快就完成了。还有一个 bool[]指示任务是否执行到最后看起来真的很难看,因为我认为 ManualResetEvent 可以做同样的工作。谁能给我一个建议?

最佳答案

好吧,您可以自己构建它,但我认为使用 TPL Dataflow 会容易得多.

类似于:

static async Task DoWork()
{
// By default, ActionBlock uses MaxDegreeOfParallelism == 1,
// so AThreadUnsafeMethod is not called in parallel.
var block = new ActionBlock<Item>(AThreadUnsafeMethod);

// Start off N tasks, each asynchronously acquiring 10 items.
// Each item is sent to the block as it is received.
var tasks = Enumerable.Range(0, N).Select(Task.Run(
async () =>
{
for (int i = 0; i != 10; ++i)
block.Post(await GetItemAsync());
})).ToArray();

// Complete the block when all tasks have completed.
Task.WhenAll(tasks).ContinueWith(_ => { block.Complete(); });

// Wait for the block to complete.
await block.Completion;
}

关于c# - 异步/等待任务和 WaitHandle,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12110145/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com