Mijn programma hangt bij het bewerken en importeren van bepaalde data. FunctionX bewerkt de data en een subroutine SavetoDatabase() schrijft de data naar de database. Het verwerken van ongeveer 4500 regels nam op mijn computer 10 seconden in beslag. Ongeveer 1 seconde voor FunctionX en de rest voor het inserten van de gegevens in de database (dat is duidelijk de vertragende factor). Als oplossing kan ik de backgroundworker class gebruiken, zoals in het volgende voorbeeld geillustreerd (SavetoDatabase() wordt afgehandeld door de backgroundworker).
In dit geval krijg ik echter een Invalid Operation Exception (This BackgroundWorker is currently busy and cannot run multiple tasks concurrently). De reden is natuurlijk dat de code de DoWork event opnieuw wil uitvoeren terwijl deze nog busy is. De SavetoDatabase method is nog lang niet klaar voor de volgende line al weer moet worden verwerkt.
De oplossing is volgens mij om de hele Do/Loop in het DoWork event te plaatsen (op deze manier ondervang je ook het probleem van de FunctieX vertraging). Het probleem is echter dat het StreamReader object in een aantal gevallen reeds een bepaalde readline positie bevat en dit object dus moet worden doorgegeven aan het DoWork event. Ik heb alleen geen idee hoe ik dit moet doen.
Zoals ik in gedachte heb dat het moet worden:
Is dit een goede oplossing voor het gebruik van de backgroundworker of hebben jullie andere suggesties? En zo ja, hoe moet ik het StreamReader object doorgeven aan het DoWork event?
Visual Basic .NET:
1
2
3
4
5
6
| Dim WithEvents BackgroundWorker As New BackgroundWorker ------------------ Do line = sr.ReadLine() If FunctionX(line) = True Then BackgroundWorker.RunWorkerAsync() Loop Until sr.EndOfStream = True |
Visual Basic .NET:
1
2
3
4
5
| Private Sub backgroundWorker_DoWork(ByVal sender As Object, ByVal e As DoWorkEventArgs) Handles BackgroundWorker.DoWork SavetoDatabase() 'database insert actie End Sub |
In dit geval krijg ik echter een Invalid Operation Exception (This BackgroundWorker is currently busy and cannot run multiple tasks concurrently). De reden is natuurlijk dat de code de DoWork event opnieuw wil uitvoeren terwijl deze nog busy is. De SavetoDatabase method is nog lang niet klaar voor de volgende line al weer moet worden verwerkt.
De oplossing is volgens mij om de hele Do/Loop in het DoWork event te plaatsen (op deze manier ondervang je ook het probleem van de FunctieX vertraging). Het probleem is echter dat het StreamReader object in een aantal gevallen reeds een bepaalde readline positie bevat en dit object dus moet worden doorgegeven aan het DoWork event. Ik heb alleen geen idee hoe ik dit moet doen.
Zoals ik in gedachte heb dat het moet worden:
Visual Basic .NET:
1
2
3
4
| Dim WithEvents BackgroundWorker As New BackgroundWorker ------------------ BackgroundWorker.RunWorkerAsync() |
Visual Basic .NET:
1
2
3
4
5
6
| Private Sub backgroundWorker_DoWork(ByVal sender As Object, ByVal e As DoWorkEventArgs) Handles BackgroundWorker.DoWork Do line = sr.ReadLine() If FunctionX(line) = True Then SavetoDatabase() Loop Until sr.EndOfStream = True End Sub |
Is dit een goede oplossing voor het gebruik van de backgroundworker of hebben jullie andere suggesties? En zo ja, hoe moet ik het StreamReader object doorgeven aan het DoWork event?