Ik ben al een aantal dagen aan het klooien om het volgende scenario voor elkaar te krijgen:
De main thread van een applicatie spawnt een thread (of backgroundworker). Deze thread spawnt op zijn beurt (bijv) 20 backgroundworkers die allemaal parallel een proces moeten uitvoeren. Deze backgroundworkers geven een ProgressReport en de thread erboven (of de 'main backgroundworker') pakt dit event op. Vervolgens weet het dat hij deze gegevens weer verder naar boven moet duwen, dus op zijn beurt vuurt deze thread (of dus de main backgroundworker) zijn eigen ProgressChangedEvent met de gegevens van het binnengekomen child-progressreport.
Het is dus een soort 'bucket brigade' van voortgangsrapporten die van een groep werkers (backgroundworkers) doorgegeven wordt aan de 'opzichter' (main backgroundworker) die het vervolgens naar de 'baas' (main thread) doorgeeft.
Ik gebruik backgroundworkers omdat je dan geen geneuzel hebt met cross-threading exceptions of allerlei vormen van locking en synchronisatie (de progress reports worden namelijk gefired door de 'background thread' zelf MAAR worden opgepakt en de event handler wordt uitgevoerd door de thread die de backgroundthread geinstantieerd heeft). Daarnaast lijkt het mij een goed idee om events te gebruiken met 'voortgangsrapporten' om geen domme idle loops te maken die actief aan het wachten zijn op voortgang (de 'opzichter' en 'baas' hebben zelf ook nog wel wat te doen). Het voordeel is ook dat de werker processen geen kennis hoeven te hebben WIE iets met hun voortgangsrapporten doet, en hoeveel lager (threads) er eventueel boven liggen en of zij extra properties aan hun rapport toevoegen.
MAAR: op de een of andere manier zorgt deze aanpak ervoor dat de voortgangsrapporten niet in de juiste volgorde bij de opzichter (en dan dus ook niet bij de baas) aankomen! Het kan dus zijn dat je bij de progresseventhandler van de main backgroundworker een rijtje percentages van een worker ziet zoals: ...30, 31, 32, 33, 35, 36, 37, 38, 34, 39...
Dat is niet acceptabel voor mijn applicatie (voor welke wel?!?).
Het vreemdste is nog dat als je de 'opzichter' thread er tussenuit haalt en de workers direct aan de mainthread rapporteren, dit fenomeen zich niet voordoet.
Ik heb als alternatief ook geprobeerd dit met een 'AsyncOperation' te doen (samen met de 'AsyncOperation.Post', maar dan gebeurt het zelfde (niet vreemd: een backgroundworker gebruikt intern ook een AsyncOperation)).
Hoe kan het zijn dat de progress event handler de progress reports niet in de juiste volgorde ontvangt en hoe los ik dit elegant op?
Ik heb nu geen compact codevoorbeeld gemaakt om dit te illustreren, eventueel kan ik dat later nog toevoegen aan de post.
De main thread van een applicatie spawnt een thread (of backgroundworker). Deze thread spawnt op zijn beurt (bijv) 20 backgroundworkers die allemaal parallel een proces moeten uitvoeren. Deze backgroundworkers geven een ProgressReport en de thread erboven (of de 'main backgroundworker') pakt dit event op. Vervolgens weet het dat hij deze gegevens weer verder naar boven moet duwen, dus op zijn beurt vuurt deze thread (of dus de main backgroundworker) zijn eigen ProgressChangedEvent met de gegevens van het binnengekomen child-progressreport.
Het is dus een soort 'bucket brigade' van voortgangsrapporten die van een groep werkers (backgroundworkers) doorgegeven wordt aan de 'opzichter' (main backgroundworker) die het vervolgens naar de 'baas' (main thread) doorgeeft.
Ik gebruik backgroundworkers omdat je dan geen geneuzel hebt met cross-threading exceptions of allerlei vormen van locking en synchronisatie (de progress reports worden namelijk gefired door de 'background thread' zelf MAAR worden opgepakt en de event handler wordt uitgevoerd door de thread die de backgroundthread geinstantieerd heeft). Daarnaast lijkt het mij een goed idee om events te gebruiken met 'voortgangsrapporten' om geen domme idle loops te maken die actief aan het wachten zijn op voortgang (de 'opzichter' en 'baas' hebben zelf ook nog wel wat te doen). Het voordeel is ook dat de werker processen geen kennis hoeven te hebben WIE iets met hun voortgangsrapporten doet, en hoeveel lager (threads) er eventueel boven liggen en of zij extra properties aan hun rapport toevoegen.
MAAR: op de een of andere manier zorgt deze aanpak ervoor dat de voortgangsrapporten niet in de juiste volgorde bij de opzichter (en dan dus ook niet bij de baas) aankomen! Het kan dus zijn dat je bij de progresseventhandler van de main backgroundworker een rijtje percentages van een worker ziet zoals: ...30, 31, 32, 33, 35, 36, 37, 38, 34, 39...
Dat is niet acceptabel voor mijn applicatie (voor welke wel?!?).
Het vreemdste is nog dat als je de 'opzichter' thread er tussenuit haalt en de workers direct aan de mainthread rapporteren, dit fenomeen zich niet voordoet.
Ik heb als alternatief ook geprobeerd dit met een 'AsyncOperation' te doen (samen met de 'AsyncOperation.Post', maar dan gebeurt het zelfde (niet vreemd: een backgroundworker gebruikt intern ook een AsyncOperation)).
Hoe kan het zijn dat de progress event handler de progress reports niet in de juiste volgorde ontvangt en hoe los ik dit elegant op?
Ik heb nu geen compact codevoorbeeld gemaakt om dit te illustreren, eventueel kan ik dat later nog toevoegen aan de post.