Parallel.Foreach e BulkCopy

parallel-foreach sqlbulkcopy

Domanda

Ho una libreria C # che si connette a 59 server della stessa struttura di database e importa i dati sul mio db locale sulla stessa tabella. In questo momento sto recuperando il server dati per server nel ciclo 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);
    }
}

Perché ci sono molti sistemi per recuperare i dati, mi chiedo se è possibile utilizzare il ciclo Pararel.Foreach? BulkCopy bloccherà la tabella durante WriteToServer e il prossimo WriteToServer aspetterà fino a quando il precedente sarà completato?

- MODIFICA 1

Ho cambiato Foreach in Parallel.Foreach ma devo affrontare un problema. All'interno di questo ciclo ho un metodo async: _systemService.GetConnectionStringAsync (systemDto.Ip) e questa riga restituisce l'errore:

System.NotSupportedException: una seconda operazione avviata in questo contesto prima che fosse completata una precedente operazione asincrona. Utilizzare 'attendi' per assicurarsi che tutte le operazioni asincrone siano state completate prima di chiamare un altro metodo in questo contesto. Non è garantito che tutti i membri di istanza siano thread-safe.

Qualche idea come posso gestire questo?

Risposta esperta

In generale, verrà bloccato e attenderà fino al completamento dell'operazione precedente.

Ci sono alcuni fattori che possono influenzare se SqlBulkCopy può essere eseguito in parallelo o meno.

Ricordo che quando aggiungevo la funzione Parallel al mio .NET Bulk Operations , avevo difficoltà a farlo funzionare correttamente in parallelo ma funzionava bene quando la tabella non ha indice (il che probabilmente non è mai il caso)

Anche quando ha funzionato, il guadagno di prestazioni non è stato molto più veloce.

Forse troverai maggiori informazioni qui: MSDN - Importazione di dati in parallelo con blocco a livello di tabella



Autorizzato sotto: CC-BY-SA with attribution
Non affiliato con Stack Overflow
Autorizzato sotto: CC-BY-SA with attribution
Non affiliato con Stack Overflow