Ho un codice che scorre un elenco di record, avvia un'attività di esportazione per ciascuno e aumenta un contatore di avanzamento di 1 ogni volta che un'attività termina, in modo che l'utente sappia quanto è lungo il processo.Come posso tenere traccia di quante attività asincrone sono state completate in un ciclo?
Ma a seconda del tempo dei miei loop, vedo spesso l'output che mostra un numero più alto prima di un numero inferiore.
Per esempio, mi sarei aspettato di vedere l'uscita in questo modo:
Exporting A Exporting B Exporting C Exporting D Exporting E Finished 1/5 Finished 2/5 Finished 3/5 Finished 4/5 Finished 5/5
Ma invece io ottenere output come questo
Exporting A Exporting B Exporting C Exporting D Exporting E Finished 1/5 Finished 2/5 Finished 5/5 Finished 4/5 Finished 3/5
Non mi aspetto che l'uscita per l'esattezza da quando ho' m non blocca il valore quando lo aggiorno/utilizzo (a volte emette lo stesso numero due volte o salta un numero), tuttavia non mi aspetto che vada indietro.
Il mio set di dati di test è di 72 valori, e il relativo codice è simile al seguente:
var tasks = new List<Task>();
int counter = 0;
StatusMessage = string.Format("Exporting 0/{0}", count);
foreach (var value in myValues)
{
var valueParam = value;
// Create async task, start it, and store the task in a list
// so we can wait for all tasks to finish at the end
tasks.Add(
Task.Factory.StartNew(() =>
{
Debug.WriteLine("Exporting " + valueParam);
System.Threading.Thread.Sleep(500);
counter++;
StatusMessage = string.Format("Exporting {0}/{1}", counter, count);
Debug.WriteLine("Finished " + counter.ToString());
})
);
}
// Begin async task to wait for all tasks to finish and update output
Task.Factory.StartNew(() =>
{
Task.WaitAll(tasks.ToArray());
StatusMessage = "Finished";
});
L'uscita può apparire invertiti in entrambe le istruzioni di debug e il StatusMessage
uscita.
Qual è il modo corretto per tenere il conto di quante attività asincrone in un ciclo sono state completate in modo che questo problema non si verifichi?
Sei sicuro che il 'Async' Prcess è garantito per l'uscita in un' Ascendente Order' Sulla base di quello che ho sto vedendo che non penso che lo farà a meno che tu non faccia un 'Sort' sulla' Lista ' –
MethodMan
Dato che stai iniziando tutte le attività essenzialmente nello stesso tempo, finiranno in un ordine casuale. Anche se usi Interlocked.Increment "Finished n/5" non sarà monotona. – Phil
@DJKRAZE La variabile 'counter' non dovrebbe essere aumentata fino al termine dell'esportazione (sostituito da' Thread.Sleep' a scopo di test). Differenti esportazioni richiedono tempi di completamento diversi a seconda della quantità di dati che contengono, quindi non desidero il valore predefinito all'inizio dell'attività asincrona. Invece, sto tentando di utilizzare una variabile condivisa che viene aumentata di 1 ogni volta che viene completata un'attività di esportazione. – Rachel