У меня есть библиотека C #, которая соединяется с 59 серверами одной и той же структуры базы данных и импортирует данные в локальную базу данных в ту же таблицу. В этот момент я получаю сервер данных сервером в цикле foreach:
foreach (var systemDto in systems)
{
var sourceConnectionString = _systemService.GetConnectionStringAsync(systemDto.Ip).Result;
var dbConnectionFactory = new DbConnectionFactory(sourceConnectionString,
"System.Data.SqlClient");
var dbContext = new DbContext(dbConnectionFactory);
var storageRepository = new StorageRepository(dbContext);
var usedStorage = storageRepository.GetUsedStorageForCurrentMonth();
var dtUsedStorage = new DataTable();
dtUsedStorage.Load(usedStorage);
var dcIp = new DataColumn("IP", typeof(string)) {DefaultValue = systemDto.Ip};
var dcBatchDateTime = new DataColumn("BatchDateTime", typeof(string))
{
DefaultValue = batchDateTime
};
dtUsedStorage.Columns.Add(dcIp);
dtUsedStorage.Columns.Add(dcBatchDateTime);
using (var blkCopy = new SqlBulkCopy(destinationConnectionString))
{
blkCopy.DestinationTableName = "dbo.tbl";
blkCopy.WriteToServer(dtUsedStorage);
}
}
Поскольку существует множество систем для извлечения данных, мне интересно, можно ли использовать цикл Pararel.Foreach? Будет ли BulkCopy блокировать таблицу во время WriteToServer, и следующий WriteToServer будет ждать, пока предыдущий не завершится?
- ИЗМЕНИТЬ 1
Я изменил Foreach на Parallel.Foreach, но я столкнулся с одной проблемой. Внутри этого цикла у меня есть метод async: _systemService.GetConnectionStringAsync (systemDto.Ip), и эта строка возвращает ошибку:
System.NotSupportedException: вторая операция началась в этом контексте до завершения предыдущей асинхронной операции. Используйте «ждут», чтобы убедиться, что какие-либо асинхронные операции были выполнены до вызова другого метода в этом контексте. Любые члены экземпляра не гарантируют безопасность потоков.
Любые идеи, как я могу справиться с этим?
В общем, он будет заблокирован и будет ждать завершения предыдущей операции.
Есть некоторые факторы, которые могут повлиять, если SqlBulkCopy
можно запустить параллельно или нет.
Я помню, когда добавлял функцию Parallel
в свои .NET Bulk Operations , у меня было нелегкое время, чтобы она работала правильно параллельно, но это сработало, когда таблица не имеет индекса (что, вероятно, никогда не будет)
Даже когда работала, прирост производительности был не намного быстрее.
Возможно, вы найдете здесь дополнительную информацию: MSDN - импорт данных в параллель с блокировкой уровня таблицы