2

У меня типа объекта базы данных Entity, длинный список Thingy и методуправления потоками с ASP.NET асинхронномом/ждать

private Task<Entity> MakeEntity(Thingy thingy) { 
    ... 
} 

MakeEntity делает много вещей, и ЦП. Я хотел бы преобразовать все мои вещи в объекты и сохранить их в db.context. Учитывая, что

  • Я не хочу, чтобы закончить как можно быстрее
  • Количество лиц велико, и я хочу, чтобы эффективно использовать базу данных, поэтому я хочу, чтобы начать экономить изменения и ожидания пульта дистанционного управления база данных, чтобы сделать это вещь

как я могу это сделать? Мне бы очень хотелось, чтобы цикл был в ожидании, когда база данных выполнит свою работу, и предложит все недавно созданные объекты до тех пор, пока база данных не обработает их все. Какой там лучший маршрут? Я запустил команду saveChanges, если он называется одновременно, поэтому я не могу этого сделать. Мне бы очень хотелось, чтобы поток thread из восьми потоков (или, точнее, столько потоков, что у меня есть), чтобы работать с ЦП, и одна нить выполняла SaveChanges()

+1

Вы уверены, что хотите * многопоточность на ASP.NET? Помните, что когда один запрос использует несколько потоков, это значительно повлияет на вашу масштабируемость, поскольку эти потоки не могут использоваться для других запросов. –

+0

"длинный список Thingy". Вы вызываете 'MakeEntity' несколько раз с каждым экземпляром Thingy? –

+0

Кроме того, не существует способа для пакетной обработки обработанной вами частички «Thingy's» и привязывания результирующей «сущности» к контексту, ** затем ** «SaveChanges» только для одной поездки в оба DB? –

ответ

2

Это своего рода «асинхронный поток», который всегда немного неудобен.

В этом случае (если вы действительно сделать хочет распараллелить на ASP.NET, что не рекомендуется вообще), я бы сказал, что TPL Dataflow является лучшим вариантом. Вы можете использовать TransformBlock с MaxDegreeOfParallelism set to 8 (or unbounded, for that matter) и связать его с ActionBlock, который делает SaveChanges.

Помните, использовать синхронные подписи (не async/await) для CPU связанного кода, и асинхронные методы ввода-вывода связанного кода/(т.е. SaveChangesAsync).

2

Вы можете настроить конвейер из N рабочих ЦП, работающих в базу данных. Работник базы данных мог бы загружать элементы.

Поскольку MakeEntity связан с ЦП, нет необходимости использовать async и await. await не создает задачи или потоки (распространенное заблуждение).

var thingies = ...; 
var entities = thingies.AsParallel().WithDOP(8).Select(MakeEntity); 
var batches = CreateBatches(entities, batchSize: 100); 

foreach (var batch in batches) { 
Insert(batch); 
} 

Вы должны обеспечить метод, который создает партию из IEnumerable. Это доступно в Интернете.

Если вам не нужна партия для части базы данных, вы можете удалить этот код.

Для части базы данных вы, вероятно, don't need async IO, потому что это похоже на низкочастотную операцию.

Смежные вопросы