#c# #design-patterns
Вопрос:
У меня есть сложный шаблон компоновщика, реализованный в коде, аналогичном последнему в этом URL-адресе. Цель разработчиков состоит в том, чтобы построить SQL-запрос на основе свойств объекта.
Что-то вроде
PersonQueryBuilder person =
new PersonQueryBuilder.Builder()
.BuildAddressClause(request.PersonInformation.Address)
.BuildBankAccountClause(request.PersonInformation.BankAccountInformation)
.BuildAClause(request.Something)
.BuildBClause(request.Something)
.build();
Я подумал, что вместо последовательного выполнения этих логик построения было бы более эффективно, если бы я мог запускать их с
TaskFactory.StartNew(() =>
{
// Create builder here so that the builder pattern stays the same, but the process runs concurrently.
});
Есть ли какой-либо способ/пример, который может продемонстрировать подобное поведение?
Комментарии:
1. Вы создаете строки, так что это уже не должно занимать много времени: запуск их в отдельных потоках, вероятно, займет больше времени, учитывая требуемую сортировку.
2. Я предлагаю вам взглянуть на разглагольствования Эрика Липперта о производительности : «не вносите изменений, основанных на производительности, если вы не выявили проблему с производительностью».
3. У вас есть реальная проблема? Потому что StartNew, скорее всего, создаст их?
4. Ну что ж! Для 5 из 13 строителей есть 3 вызова службы. Обычно API 2 сторонних сервисов требует времени (m n). А остальные строители-это простые манипуляции со строками и немного LINQ. В результате строителям требуется время, и мой SLA API становится m n x; x-время работы API службы.
Ответ №1:
Прежде всего, с недавним C#, который вы используете Task.Run(...)
вместо TaskFactory.StartNew(...)
запуска фоновой задачи, запускающей функцию. Однако это не приведет к параллельному запуску сборщиков, для распараллеливания работы, связанной с процессором (я предполагаю, что сборщики не выполняют никаких операций ввода-вывода с диска/сети), вы используете Parallel
класс, который, Parallel.Invoke
похоже, подходит для вашего случая.
Однако при использовании параллельного класса вам необходимо убедиться, что разные разработчики не изменяют одно и то же состояние, например, не манипулируют общим StringBuilder
представлением SQL-запроса. Если вам нужно изменить одно и то же состояние, вы можете при необходимости ввести блокировки для обеспечения потокобезопасности, однако убедитесь, что распараллеливание действительно оправдано.