foreach 循环中的异步调用

更多的概念问题......是否有任何理由在像这样的 foreach 循环中对我的 DataContext 进行异步调用是一个坏主意?


private async Task ProcessItems(List<Item> items)

{

    var modifiedItems = new List<modifiedItem>();


    foreach (var item in items)

    {

        // **edited to reflect link between items and properties**

        // var properties = await _context.Properties

        //   .Where(p => p.Condition == true).ToListAsync();

        var properties = await _context.Properties

          .Where(p => p.Condition == item.Condition).ToListAsync();


        foreach (var property in properties)

        {

            // do something to modify 'item'

            // based on the value of 'property'

            // save to variable 'modifiedItem'


            modifiedItems.Add(modifiedItem)

        }

    }


    await _context.ModifiedItems.AddRangeAsync(modifiedItems);

    await _context.SaveChangesAsync();

}

由于内部 foreach 循环依赖于properties变量,它是不是在properties变量完全实例化后才开始?


由于modifiedItems变量是在父 foreach 循环之外声明的,将每个异步添加modifiedItem到modifiedItems列表中是不是一个坏主意?


实体框架、Linq 中是否有任何属性/方法,或者更适合此类任务的任何属性/方法?比做嵌入式 foreach 循环更好的主意?


(如果有人想要一些上下文...... IRL,items是来自传感器的读数列表。并且properties是将原始读数转换为有意义的数据(例如不同单位的体积和重量)的数学方程......然后这些计算出的数据点正在存储在数据库中。)


繁星coding
浏览 362回答 3
3回答

达令说

不,没有,但是你在这里错过了一些概念。由于您使用异步方法,因此ProcessItems应调用该方法ProcessItemsAsync并返回一个task.这对您有用:Async/Await - Best Practices in Asynchronous Programming看你的需求了,建议添加CancellationToken并考虑异常处理,注意不要吞下异常。

HUWWW

在这种特定情况下,我改为编写它来加载所有感兴趣的传感器的所有属性的单个列表(考虑所有items并基于您macAddress/sensorKey您提到的属性),并将其存储在列表中。我们称之为allProperties。我们await一次并避免重复进行数据库调用。然后,使用 LINQ To Objects 将您items的对象连接到allProperties它们匹配的对象。迭代该连接的结果,await循环内无需执行任何操作。

慕尼黑的夜晚无繁华

这里使用异步没有问题,一旦等待异步调用,返回的对象是相同的。如果您可以在循环外运行一次数据库调用,并过滤内存中的数据以对其执行操作,您可能需要重新考虑在 foreach 中执行数据库调用。每个用例都不同,您必须确保可以在内存中处理更大的返回集。通常从数据库中获取 1000 行一次比 100 行快 10 倍。
打开App,查看更多内容
随时随地看视频慕课网APP