我有要处理的批次 list 。永远。
我想并行执行每个块(5),完成后移到下一个块。
由于某种原因,下面的代码不会等待块完成,即使没有完成也要继续执行。

while (true)
{
    foreach (string[] urlsArr in chunks)
    {
        int i = 0;
        foreach (var url in urlsArr)
        {
            ThreadPool.QueueUserWorkItem(x =>
            {
                ProccessUrl(url, config, drivers[i]);
                _resetEvent.Set();
                i++;
            });
        }
        _resetEvent.WaitOne();// this is not really waiting.
    }
}

最佳答案

这是带有Tasks(async/await)的版本

while (true)
        {
            foreach (string[] urlsArr in chunks)
            {
                Task[] tasks = new Task[urlsArr.Length];
                for (int i = 0; i < urlsArr.Length; i++)
                {
                    var url = urlsArr[i];
                    var driver = drivers[i];
                    tasks[i] = Task.Run(() => { ProccessUrl(url, config, driver); });
                }

                await Task.WhenAll(tasks);
            }
        }

请注意,它还解决了原始代码中'i'变量的问题,该变量没有以线程安全的方式递增(可以通过Interlocked.Increment修复)。

如果您的代码不是async,则可以等待任务在线程中完成(但这正在阻塞)
Task.WhenAll(tasks).Wait();

10-04 19:14