我要做的是从一个表中获取大约400万行的行来为ElasticSearch索引它。
底层索引器将使用IndexManyAsync并批量处理给它的可枚举。
类似的东西:
public void IndexMany(IEnumerable<IIndexModel> indexModels) {
var client = new ElasticClient(settings);
var batches = indexModels.Batch(1000);
var tasks = new List<Task>();
Parallels.ForEach(partitions, partition =>
{
var task = client.IndexManyAsync(partition);
tasks.Add(task);
}
Task.WaitAll(tasks.ToArray());
}
所以考虑到这一点我想用IndexModels创建一个可枚举的。
IndexModels将获取一个实体并通过给定实体初始化各种属性。类似的东西:
public class FooModel<T> : IIndexModel
{
public FooModel(T entity)
{
Name = entity.Name;
}
public string Name { get; set; }
}
我有一个包含~4mil行的表,显然需要一些时间来查询。所以我想做的就是做这个异步。
我尝试了各种方法。第一种方法是批量查询并对其进行相似的操作。这给ObjectContext带来了各种并发问题。
public void IndexAllModels() {
using (var db = new Db()) {
var batchedEntities = db.BigTable.Select(p => p).Batch(1000);
Parallels.ForEach(batchedEntities, currentBatch =>
{
var indexModels = new List<IIndexModel>();
foreach (var entity in currentBatch)
{
var indexModel = new FooModel<BigTable>(entity);
indexModels.Add(indexModel);
}
IndexMany(indexModels);
}
}
}
我想知道是否有任何方法可以通过使用新的EF6异步操作来实现这一点?
答案 0 :(得分:2)
使用自然async
API的优点是您不需要使用线程来使用它们。从一直到WinAPI级别There Is No Thread。
您可以创建一个采用IEnumerable<IndexModel>
并使用ElasticSearchs异步API的方法,如下所示:
public async Task IndexManyAsync(IEnumerable<IIndexModel> indexModels)
{
var client = new ElasticClient(settings);
var taskBatches = indexModels.Batch(1000)
.Select(partition =>
client.IndexManyAsync(partition));
await Task.WhenAll(taskBatches);
}
假设IndexManyAsync
为每个请求使用单独的DbContext
,这应该可以。