简体   繁体   English

并发处理项目并顺序写入结果?

[英]Process items concurrently and write the results sequentially?

The following Python code (from Read in parallel and write sequentially? ) processes (reads) the data for ID 0 to N. There readers run in parallel and it writes the result in the order of ID.以下 Python 代码(从并行读取和顺序写入? )处理(读取)ID 0 到 N 的数据。读取器并行运行,并按 ID 的顺序写入结果。 How to implement it in C# efficiently?如何在C#中有效地实现它?

async def reader(q, id_to_data, data_ready):  # Multiple readers are run in parallel
    while True:
        id = await q.get()
        data = await read_async(id) 
        id_to_data[id] = data
        data_ready.set()

async def main():
    q = asyncio.Queue()
    for id in range(1000):
        await q.put(id)

    id_to_data = {}
    data_ready = asyncio.Event()
    readers = [asyncio.create_task(reader(q, id_to_data, data_ready))
               for _ in range(3)]

    for id in range(1000):
       while True:
           # wait for the current ID to appear before writing
           if id in id_to_data:
               data = id_to_data.pop(id)
               await data.write_async(f'{id}.csv')
               break
               # move on to the next ID
           else:
               # wait for new data and try again
               await data_ready.wait()
               data_ready.clear()

    for r in readers:
        r.cancel()

C#: C#:

void main() {
    List<int> ids = get_IDs();
    ProcessAllIDs(ids);
}

async Task ProcessAllIDs(List<int> ids) {
    // A low efficient implementation
    for (var id in ids) {
        var result = await Process1(id); // Can be run concurrently
        await Process2(result); // Need to be run sequentially 
    }
}

A simple way would be to create a List of Tasks and then await in them in sequence:一种简单的方法是创建一个任务列表,然后按顺序等待它们:

var list = new List<Task<int>> { Calculate(2), Calculate(7), Calculate(19) };

foreach(var task in list)
{
  Console.WriteLine(await task);
}

static async Task<int> Calculate(int x)
{
  await Task.Delay(200);
  return x*x;
}

This will start 3 Tasks that calculate stuff simultaneously and then print the results in order.这将启动 3 个同时计算内容的任务,然后按顺序打印结果。

So for your example, it would look like this:因此,对于您的示例,它看起来像这样:

async Task main() {
    List<int> ids = get_IDs();
    await ProcessAllIDs(ids);
}

async Task ProcessAllIDs(List<int> ids) {
    var tasks = ids.Select(id => Process1(id)).ToList();
    for (var t in tasks) {
        await Process2(await t); // Need to be run sequentially 
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM