我正在使用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倍。
问题:为什么时间不同,我的假设是否正确?
答案 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);
}
}
请注意,您可能会在同一连接中运行可导致其超时的所有查询。