Parallel.Foreach et BulkCopy

parallel-foreach sqlbulkcopy

Question

J'ai une bibliothèque C # qui se connecte à 59 serveurs de la même structure de base de données et importe les données de ma base de données locale dans la même table. En ce moment, je récupère un serveur de données par serveur en boucle 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);
    }
}

Comme il existe de nombreux systèmes pour récupérer des données, je me demande s’il est possible d’utiliser la boucle Pararel.Foreach? BulkCopy verrouillera-t-il la table pendant WriteToServer et le prochain WriteToServer attendra-t-il que le précédent soit terminé?

- EDIT 1

J'ai changé Foreach en Parallel.Foreach mais je suis confronté à un problème. Dans cette boucle, j'ai une méthode asynchrone: _systemService.GetConnectionStringAsync (systemDto.Ip) et cette ligne renvoie une erreur:

System.NotSupportedException: une deuxième opération a démarré dans ce contexte avant la fin d'une précédente opération asynchrone. Utilisez 'wait' pour vous assurer que toutes les opérations asynchrones sont terminées avant d'appeler une autre méthode sur ce contexte. Il n'est pas garanti que les membres d'instance soient thread-safe.

Des idées comment puis-je gérer cela?

Réponse d'expert

En général, il sera bloqué et attendra que l'opération précédente soit terminée.

Certains facteurs peuvent affecter si SqlBulkCopy peut être exécuté en parallèle ou non.

Je me souviens de l’ajout de la fonctionnalité Parallel à mes opérations en bloc .NET , j’avais du mal à la faire fonctionner correctement en parallèle, mais cela fonctionnait bien lorsque la table n’avait aucun index (ce qui n’est probablement jamais le cas)

Même au travail, le gain de performance n’était pas beaucoup plus rapide.

Vous trouverez peut-être plus d'informations ici: MSDN - Importation de données en parallèle avec le verrouillage au niveau de la table



Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi
Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi