[Visual Basic] Kód se spouští ve špatném pořadí

C++, C#, Visual Basic, Delphi, Perl a ostatní

Moderátor: Moderátoři Živě.cz

Odeslat příspěvekod Kyong 26. 1. 2016 13:44

Mám takový problém, na který jsem předtím ještě nenarazil. Mám u tlačítka tento kód, jenže ten kód se jaksi spouští "pomíchaně". Nastavení textu, aby se zobrazilo, že to běží nebo ne, se zobrazuje až po skončení For Each. Tady je kód a tam poznámky, co je špatně.

Kód: Vybrat vše
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            If (TextBox2.Text = "") Then
            MessageBox.Show("Nevybrali jste žádnou složku")
            Label3.Text = "chyba"
        Else
             Label3.Text = "běží" ----->Spouští se až po dokončení For Each
             Dim fileNames = My.Computer.FileSystem.GetFiles(TextBox2.Text, FileIO.SearchOption.SearchAllSubDirectories, "mets*.xml")
            Dim countfiles As Integer
            countfiles = fileNames.Count
           Label7.Text = countfiles ------->Spouští se až po dokončení For Each
            For Each fileName As String In fileNames
                Dim document As XmlReader = New XmlTextReader(fileName)
                Dim fileInfo As System.IO.FileInfo
                fileInfo = My.Computer.FileSystem.GetFileInfo(fileName)
                Dim folderPath As String = fileInfo.DirectoryName
                TextBox1.AppendText(folderPath)
                TextBox1.AppendText(" - ")
                While (document.Read())
                    Dim type = document.NodeType
                    If (type = XmlNodeType.Element) Then
                        If (document.Name = "mods:title") Then
                            TextBox1.AppendText(document.ReadInnerXml.ToString())
                            TextBox1.AppendText(" - ")
                            Exit While
                        End If
                    End If
                End While
                While (document.Read())
                    Dim type = document.NodeType
                    If (type = XmlNodeType.Element) Then
                        If (document.Name = "mods:dateIssued") Then
                            TextBox1.AppendText(document.ReadInnerXml.ToString())
                            TextBox1.AppendText(" - ")
                            Exit While
                        End If
                    End If
                End While
                While (document.Read())
                    Dim type = document.NodeType
                    If (type = XmlNodeType.Element) Then
                        If (document.Name = "mods:partNumber") Then
                            TextBox1.AppendText(document.ReadInnerXml.ToString())
                            Exit While
                        End If
                    End If
                End While
                TextBox1.AppendText(vbCrLf)
            Next
            Label3.Text = "hotovo"
        End If
    End Sub
Jsem vždycky někde na netu. Vždyť síť je přece rozlehlá a nekonečná.
Kyong
Mírně pokročilý
Uživatelský avatar

Odeslat příspěvekod Nargon 26. 1. 2016 14:24

Hodnota do labelu se zapíše ihned jak je v kódu, neprobíhá žádné "náhodné" vybírání toho co se provede a co se neprovede. Ale tvůj problém je z toho jak funguje celý systém událostí. Tj musí se vykonat celý kód Button1_Click a až pak se může dělat něco dalšího, například překreslení okna aplikace. Proto se ti text zobrazí až když je to celé hotové. Pokud máš nějakou operaci co trvá delší dobu (cca 2s a více), tak je dobré na to používat vlákna, což ovšem přináší i problémy protože z jiného vlákna nelze ovládat prvky formuláře. Mě se nejvíce osvědčil backgroundworker: https://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker(v=vs.110).aspx což je takový vhodný způsob pro všechny tyhle případy kdy to něco dělá a přitom ti to dává celkem jednoduchý způsob jak to co dělá to vlákno může být zobrazováno ve formuláři, aniž by sis musel lámat hlavu s tím jak si předat data mezi jednotlivými vlákny.
Případně pokud chceš ještě jednodušší variantu, tak stačí volat metodu DoEvents která provede operace s oknem. Tj zareaguje na kliknutí, překreslí formulář apod.
https://msdn.microsoft.com/en-us/library/system.windows.forms.application.doevents(v=vs.110).aspx
Když jí dáš např na začátek toho cyklu foreach tak to bude fungovat.
Desktop: Ryzen 7 1800X (3.95GHz, 1.35V), Asus Crosshair VI Hero, 16GB DDR4 Ram (3200MHz), 128GB SSD + 3TB HDD, Nvidia GTX 1080
Notebook: Asus UL50VT 15.6" (SU7300@1.7GHz, 4GB ram, 500GB HDD, Intel GMA 4500MHD + nVidia G210M, dlouha vydrz cca 7+ hod)
Nargon
Moderátor

Odeslat příspěvekod Kyong 26. 1. 2016 14:32

Díky, použil jsem teda ten Application.DoEvents().
Jsem vždycky někde na netu. Vždyť síť je přece rozlehlá a nekonečná.
Kyong
Mírně pokročilý
Uživatelský avatar

Odeslat příspěvekod JanFiala 26. 1. 2016 14:35

Musel bys po zmene labelu vyvolat jeho aktualizaci, ale pokud to udelas pri kazde iteraci cyklu, bude to podstatne zdrzovat
Co můžeš udělat dnes, odlož na včerejšek
JanFiala
Expert
Uživatelský avatar


Kdo je online

Uživatelé procházející toto fórum: Žádní registrovaní uživatelé a 0 návštevníků