【问题标题】:How to break big foreach loop into batch and process it simultaneously?如何将大 foreach 循环分成批处理并同时处理?
【发布时间】:2019-05-13 20:21:37
【问题描述】:
foreach (var deviceId in deviceList)
{
    // register device into IoT hub 
    Device device;
    RegistryManager registryManager = RegistryManager.CreateFromConnectionString("connectionString");
    device = await registryManager.AddDeviceAsync(new Device(deviceId));

    // send message to iot hub
    DeviceClient deviceClient;
    await deviceClient.SendEventAsync("data");                       
}

如果设备是 10000,那么我如何将它分成多个批次并进行处理?

我试过这段代码,但它没有希望

public IEnumerable<user> GetBatch(int pageNumber)
{
    return users.Skip(pageNumber * 1000).Take(1000);
}

【问题讨论】:

  • 如果你想“同时”(并行)处理,你可以考虑并行化 foreach。有关Async 和Await 的一些方法,请参阅:stackoverflow.com/questions/11564506/…。如果你想将它分批,.Skip 和.Take 确实是这样做的正确方法。
  • 请发布工作代码。在此示例中为 deviceClient == null,NRE 也是如此。
  • AddDeviceAsync 和 SendEventAsync 是 CPU-bound 还是 IO-bound 操作?第一种情况最好并行工作,第二种情况需要异步代码。
  • RegistryManager 线程安全吗?我们可以同时添加来自不同线程的设备,还是需要锁定?

标签: c# loops c#-4.0 foreach batch-processing


【解决方案1】:

这是Parallel.ForEach 循环的绝佳案例,它将自动将循环处理分配到多个线程。很容易将您的代码重新安排到这样的循环中,并利用内置的并行库来启用并行处理。这当然假设顺序并不重要(而且它似乎并不基于我们能看到的一点点)。

编辑: 如果您确实需要 100 或 200 的特定批次,如评论中所述,您可以使用 System.Collections.Concurrent.Partitioner 类根据需要打破并行循环,this SO post 实际上很好地描述了如何使用它。

Parallel.ForEach(devices, (device) =>
            {
                        // register device into IoT hub 
                        Device device;
            RegistryManager registryManager = RegistryManager.CreateFromConnectionString("connectionString");
                        device = await registryManager.AddDeviceAsync(new Device(deviceId));


                        // send message to iot hub
                         DeviceClient deviceClient;
                        await deviceClient.SendEventAsync("data");                       

            });

【讨论】:

  • 但是这里我们还没有处理成批处理。批量 100 或 200。在 Parallel.ForEach 之前,如果我们可以批量处理它会很棒。你能帮助我吗?谢谢
  • 正确,它没有分成特定批次。您能否在帖子中分享更多关于所需最终结果的信息?您是否有理由将其放入 100 或 200 的特定批次中?
  • 我想分批,因为执行更多的设备列表需要很长时间。我不希望它变成 100 或 200 任何不都对我有好处。
  • 在这种情况下,最初发布的并行循环将执行您想要的操作。它将使用内置的 .NET 算法根据当前机器上可用的线程尽可能高效地分解处理。
  • Neo,相信你并不了解parallel.foreach的概念。这是刹车,所以它被并行处理,然后更快。 Yoy 想要更快,所以我相信 Steve 帮助了你
猜你喜欢
  • 2020-05-27
  • 1970-01-01
  • 1970-01-01
  • 2017-06-15
  • 2019-01-26
  • 2015-07-27
  • 2020-08-26
  • 2020-11-09
  • 2019-08-06
相关资源
最近更新 更多