Elektroda.pl
Elektroda.pl
X
Please add exception to AdBlock for elektroda.pl.
If you watch the ads, you support portal and users.

[VB] Petla for nie dziala jak nalezy

AnnaWesolaLat23 19 Nov 2009 16:19 3815 12
  • #1
    AnnaWesolaLat23
    Level 15  
    Witam.

    VB 2008 Basic Express Edition

    
    Public Class Form1
    
        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
            Dim i1 As Long
            Dim i2 As Long
    
            i1 = 0
            i2 = 0
    
            For i1 = 1 To 40000000000000
                i2 = i2 + 1
                Label1.Text = i1
                Label2.Text = i2
    
            Next i1
    
            MsgBox(i1)
            MsgBox(i2)
    
        End Sub
    
        Private Sub Label1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Label1.Click
    
        End Sub
    
        Private Sub Label2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Label2.Click
    
        End Sub
    End Class
    
    


    Jest tylko Label1 Label1 oraz guzik.
    Po uruchomieniu programiu z Label1 robi sie L oraz polowa literki a,
    z LAbel2 robi sie L oraz polowa literki a.

    Po kolejnych 10 sekundach tam gdzie jest Label1 i Label 2 jest biale pole, na naglowek zmienia sie na program nie odpowiada.

    Jezeli zmniejsze ilosc obrotow petli do bardziej sensownej wartosci np 32000 to rowniez nie widze jak labele zwiekszaja swoja wartosc w trakcie trwania petli.
  • #3
    wrych
    Level 20  
    Zmienne sterujące w pętlach for (chyba) mogą być maksymalnie typu Integer.
    Nie wiem natomiast jak wytłumaczyć fakt, że dla mniejszych liczb też tylko zobaczymy ostatni rezultat. Być może pętla for szybciej zmienia wartości zmiennej niz system zdoła wyświetlić etykietę stąd efekt taki jak opisujesz...
  • #4
    Dżyszla
    Level 42  
    Wrych - system dokonuje przerysowania dopiero w momencie, gdy aplikacja jest w stanie obsłużyć wiadomość WM_PAINT. W trakcie trwania pętli wiadomość się tylko kolejkuje, ale brak jest wolnych zasobów w gównym wątku aplikacji, aby dokonać przerysowania. Stąd albo konieczne jest wymuszenie przerysowania, albo ewentualnie w petli przetworzenie kolejki wiadomości.
  • #5
    wrych
    Level 20  
    Po poprawce wg wskazówki Dżyszli
    For i1 = 1 To 40000000000000 
                i2 = i2 + 1 
                Label1.Text = i1 
                Label1.Refresch()
                Label2.Text = i2 
                Label2.Refresch()
            Next i1 
    

    program działa, ale na komputerze nic innego już nie można zrobić, bo program się zawiesi. Po co komu ten program?
  • #7
    jestam
    Automation specialist
    Quote:

    Jezeli zmniejsze ilosc obrotow petli do bardziej sensownej wartosci np 32000 to rowniez nie widze jak labele zwiekszaja swoja wartosc w trakcie trwania petli


    Program jest z zasady błędny. Żeby pokazać zmiany w kontrolce trzeba obsłużyć komunikat WM_PAINT. Komunikaty obsługuje pętla komunikatów, kolejno odczytując je z kolejki i wywołując procedury/funkcje obsługujące każdy z komunikatów.
    Gdy w kolejce znajdzie się WM_CLICK i zostanie wywołana procedura Sub Button1_Click(), następny komunikat (np. WM_PAINT) może być obsłużony dopiero po zakończeniu wykonania Button1_Click().

    Z zasady, nie tędy droga. Poprawny program powinien obsługiwać zdarzenia (komunikaty) jak najkrócej. Można np. użyć timera, którego procedura obsługi wywołana cyklicznie będzie zwiększała wartości Label1 i Label2 o 1 po czym okno zostanie odrysowane. Button1_Clik() zainicjuje wartością 0, po osiągnięciu max wartości timer zostanie zatrzymany.

    W pewnym zakresie problem można obejść przez wywołanie Label1.Refresh() i Label2.Refersh(). W VB.NET jest też dostępna metoda Application.DoEvents(), która umieszczona wewnątrz pętli wymusi obsługę zdarzeń. Wada jest taka, że ktoś może ponownie kliknąć przycisk, uruchamiając obsługę Button1_Click() ponownie.
  • #8
    AnnaWesolaLat23
    Level 15  
    @Dżyszla
    To jest przyklad edukacyjny dla mnie, bez konkretniego zastosowania.
    Chce zeby chodzilo jak zolt, i chce zeby to sie wyswietlalo.
    Jak w petli jest polecenie wyswietl to sie ma wyswietlac, tak jak to jest w Pascalu c qbasicu itp.

    @wrych
    Rozumiem pojecie MHz/GHz i rozumiem to ze kazdy rozkaz zajmuje iles tam cykli zegarowych, wiec smialo ;-) Liczba dlatego jest duza zebym zauwazyla ze Label1 i 2 sie zmieniaja.

    @jestam + wszyscy
    Czyli tak naprawde jest wyswietlanie na ekranie, gdy wyjdzie z podprogramu wykonywania klikniecie tego guzika?

    @A.ll
    A czy koledzy moga pomoc mi w tym watku:
    https://www.elektroda.pl/rtvforum/topic1477740.html
    Chodzi o to ze mam tabelke typow.
    I w glownym programie deklaruje elementy tabelki i sie nie da.

    Tak definiuje strukture:
    Structure Pytania
    Dim odpowiedz As String
    Dim Punktow As Integer
    End Structure

    Tak tablice:
    Dim Tablica(9, 4) As Pytania


    Tak chce zapelnic tablice i sie nie da.
    Tablica(0,0).odpowiedz = "lajkonik"
    Tablica(0,0).punktow = 2

    ------------

    Moze inaczej sformuluje pytanie:
    [VB] Petla for nie dziala jak nalezy
    Jak mam zdefiniowac zmienne globalne i przypisac do nich wartosc?
  • #9
    jestam
    Automation specialist
    AnnaWesolaLat23 wrote:

    Jak w petli jest polecenie wyswietl to sie ma wyswietlac, tak jak to jest w Pascalu c qbasicu itp.


    Pascal, C i QBasic pracują pod DOSem. W Windows "Jak w petli jest polecenie wyswietl" to nie będzie się wyświetlać. Chyba że

    jestam wrote:
    W pewnym zakresie problem można obejść przez wywołanie Label1.Refresh() i Label2.Refersh(). W VB.NET jest też dostępna metoda Application.DoEvents(), która umieszczona wewnątrz pętli wymusi obsługę zdarzeń.

    Czego robić raczej nie należy, bo to zły sposób. Jak zrobić należy napisałem wyżej.

    Quote:

    @jestam + wszyscy
    Czyli tak naprawde jest wyswietlanie na ekranie, gdy wyjdzie z podprogramu wykonywania klikniecie tego guzika?

    Patrz wyżej.

    Quote:
    Jak mam zdefiniowac zmienne globalne i przypisac do nich wartosc?

    Nie definiujesz zmiennych globalnych. Zdefiniowałaś zmienną należące do klasy Form1 (czyli pole). Przypisania muszą znaleźć się w metodach klasy. Do tego celu służą konstruktory (w składni VB: Public Sub New()).

    Żeby uprościć: dodaj przypisywanie wartości wewnątrz Private Sub Form1_Load(....)
  • #11
    jestam
    Automation specialist
    Teoretyzujesz. Nie jest. Aby
    Quote:

    wykonać możliwie najwięcej wyświetleń kolejnych wartości w czasie

    trzeba użyć DirectDraw.
  • #12
    Dżyszla
    Level 42  
    Toś pojechał po bandzie teraz ;p Ale myślę, że autorce nie ma sensu zawracać głowy wątkami i wiadomościami (w rozumieniu programistycznym rzecz jasna) tylko wskazać drogę na wymuszenie odświeżenia na ekranie danej kontrolki.