Я нахожусь в центре проекта импорта данных, у меня есть старая БД, из которой я извлекаю данные, выполняю большую обработку, чтобы она "вписалась" в новую БД, а затем записываю ее в новую БД.
Я пытаюсь ускорить этот процесс, поскольку мне нужно обработать миллионы записей, а однопоточный процесс слишком медленный. В настоящее время я делаю это следующим образом:
SemaphoreSlim _sem = new SemaphoreSlim(8);
var tasks = policyVersionDictionary.Select(async pv =>
{
await _sem.WaitAsync();
await using (var dbThread = new ApplicationDbContext(connectionString))
{
try
{
dbThread.Database.SetCommandTimeout(240);
var listOfPolicyVersions = pv.Value;
var horseService = new HorseTransferServiceMultithreading(dbThread);
await horseService.ProcessHorse(listOfPolicyVersions);
}
finally
{
_sem.Release();
// Probably an overkill as we're inside 'using'
dbThread.Database.CloseConnection();
dbThread.Dispose();
}
}
}).ToArray();
await Task.WhenAll(tasks);
_sem
контролирует количество потоков, я создаю новый dbContext для каждого элемента в policyVersionDictionary, я также создаю новый HorseTransferServiceMultithreading
, как я хочу он должен быть отдельным для каждой операции (потока).
метод horseService.ProcessHorse(listOfPolicyVersions);
является методом-оболочкой для всей обработки, которую необходимо выполнить для каждого элемента, включая многократное чтение / запись в базу данных. .
Это уже работает быстрее, чем однопоточный способ сделать это, но я не уверен, является ли это правильным способом выполнения параллельной / параллельной обработки. Я прочитал тонну постов о бедствиях, которые случаются, когда вы пишете параллельный код, который читает / пишет из базы данных, взаимоблокировкам, ошибкам и всяким другим, но я недостаточно знаю об этом методе, чтобы понять, делаю это правильно или я совершаю огромную ошибку.
Есть ли лучший способ? Следует ли этого полностью избежать? Если да, то как следует решать импортируемые проекты, чтобы они были как можно быстрее? В настоящее время он работает около 48 часов (не только этот фрагмент кода), что довольно долго, и в идеале я хотел бы сделать его намного быстрее.