Sto lavorando a un'applicazione che chiama un servizio esterno e deve aggiungere tutte le voci della raccolta esterna in una raccolta locale. Il problema attualmente è che la raccolta esterna può superare i 1000 record, ma i risultati di ricerca restituiti possono includere solo fino a venti voci.Utilizzare più attività per recuperare tutti i record da una grande raccolta
Per motivi di velocità ho pensato che utilizzando una raccolta di attività sarebbe la via da seguire, così mi si avvicinò con il codice qui sotto:
int totalCount = returnedCol.total_count;
while (totalCount > myDict.Count)
{
int numberOfTasks = // logic to calculate how many tasks to run
List<Task> taskList = new List<Task>();
for (int i = 1; i <= numberOfTasks; i++)
{
Interlocked.Add(ref pageNumber, pageSize);
Task<SearchResponse> testTask = Task.Run(() =>
{
return ExternalCall.GetData(pageNumber, pageSize);
});
Thread.Sleep(100);
taskList.Add(testTask);
testTask.ContinueWith(o =>
{
foreach (ExternalDataRecord dataiwant in testTask.Result.dataiwant)
{
if (!myDict.ContainsKey(dataiwant.id))
myDict.GetOrAdd(dataiwant.id, dataiwant);
}
});
}
Task.WaitAll(taskList.ToArray());
}
Tuttavia, questo non produce tutti i risultati. La variabile pageNumber
si incrementa correttamente ogni volta, ma sembra che non tutti i risultati dell'attività vengano analizzati (poiché la stessa logica su un singolo thread su un set di dati più piccolo restituisce tutti i risultati previsti). Inoltre, ho provato a dichiarare le singole attività in una catena (piuttosto che in un ciclo) e tutti i dati di test sono stati restituiti. Sembra che più alto è il valore che passo in Thread.Sleep()
più i risultati vengono aggiunti alla raccolta locale (ma questo non è l'ideale, poiché significa che il processo richiede più tempo!)
Attualmente in un campione di 600 record I Sono solo circa 150-200 aggiunti alla collezione myDict
. Mi manca qualcosa di ovvio?
Sembra che "la logica per calcolare quanti compiti da eseguire" potrebbero essere rilevanti qui. Inoltre, quanto sei positivo che '(pageNumber, pageSize)' sia corretto? Potrei vedere il problema che si sta affrontando provenire dal fermare il ciclo prima di arrivare effettivamente alla fine della raccolta o dalla richiesta di blocchi di dati che sono in gran parte sovrapposti. – StriplingWarrior
'pageSize' non cambia mai nel mio codice in quanto è sempre impostato sul valore più alto disponibile (cioè 20). Ho testato per vedere se il valore di 'pageNumber' sta aumentando correttamente ogni volta, e inizia a comportarsi da solo (aumentando di venti ogni volta), ma inizia a diventare irregolare. Aumentare la discussione.Il periodo di sospensione ha un effetto su questo, ma dal momento che lo sto incrementando in un modo sicuro per i thread non riesco a capire perché ciò accada –
Inoltre, per motivi di test ho creato una fonte di dati esterna con una raccolta di 60 elementi e ho provato a recuperare un elemento alla volta tramite 60 attività, e non ho ancora ottenuto tutti i dati nella mia raccolta (a meno che non aumenti il periodo di sospensione) –