什么是对循环中的呼叫实体框架等待的性能影响(vs sync)

时间:2017-03-27 17:17:58

标签: c# entity-framework asynchronous async-await

我正在使用EF6,并试图了解实际发生的情况以及在紧密循环中对EF进行异步调用并运行数千次的性能影响。也就是说,这个循环:

private void createPolygones() {
    // Build polygon and load them on the map
    // list to retrieve the correct answer when we need it
    polygonList = new ArrayList<>();

    for (int j = 0; j < placemarks.size(); j++) {
        List<GeoPoint> myGeoList = new ArrayList<>();
        Placemark placemark = placemarks.get(j);
        // get all coordinate of the placemark
        for (int i = 0; i < placemark.getCoordinates().size(); i++) {
            myGeoList.add(new GeoPoint(placemark.getCoordinates().get(i)
                    .getLatitude(), placemark.getCoordinates().get(i)
                    .getLongitude()));
        }
        CustomPolygon polygon = new CustomPolygon(this);
        Log.d(TAG,"polygon point list : " + myGeoList);
        polygon.setPoints(myGeoList);
        polygon.initDefaultColor();
        polygon.setTitle(placemark.getName());
        polygonList.add(polygon);
        map.getOverlays().add(polygon);
    }
}

我的想法是在&#34;结束时使用&#34;声明,所有10000将按顺序处理。

当将它与同步调用(只是没有等待的query.ToList())进行比较时,会发生完全相同的事情并且性能应该相同。我的结果表明,运行时间差异为1.5倍。

问题:为什么时间不同,我的假设是否正确?

2 个答案:

答案 0 :(得分:0)

  

我的想法是,在“使用”声明的最后,所有的   10000将按顺序处理。

不,每次等待时都会处理它们......调用ToListAsync()。

  

问题:为什么时间不同而且是我的假设   正确的吗?

因为在尝试最大化单线程吞吐量时,使用async ... ToListAsync()会导致开销,从而导致性能损失。

答案 1 :(得分:0)

如果您添加一些内容,例如。但您需要提前了解cnt

cosnt int cnt = 10000;
const int pageSize = 1000;

int pageNumber = 0;
var list = new List<MyTableRecord>();

using (var db = dbContext())
{
    for (var i = 0; i < cnt ; i++)
    {
        vary query = db.MyTable.Where(...).Skip(pageNumber++ * pageSize).Take(pageSize);
        list.AddRange(await query.ToArrayAsync());
    }
}

请注意,list如果您尝试在其中加载1000 * 10000条记录,可能会炸毁您计算机的内存(OutOfMemoryException)。

更现实的解决方案:

using (var db = dbContext())
{
    IEnumerable<MyTableRecord> rows;
    while ((rows = db.MyTable.Where(...).Skip(pageNumber++ * pageSize).Take(pageSize)).Any())
    {
        list.AddRange(rows);
    }
}

请注意,您可能会在同一连接中运行可导致其超时的所有查询。