CYFROWY BARON • PROGRAMOWANIE • Zobacz wątek - Modyfikacja podczas działania Sleep'a

Modyfikacja podczas działania Sleep'a

dział ogólny

Modyfikacja podczas działania Sleep'a

Nowy postprzez nvdante » niedziela, 29 stycznia 2012, 02:01

Witam

Napisałem sobie maleńki programik, który ogólnie mówiąc działa, ale chciałbym go troszkę usprawnić.
Otóż program po naciśnięciu Start wykonuje pętlę, którą można przerwać przyciskiem Stop.
Pętla polega na wykonaniu polecenia, które jest opóźniane Sleep'em na konkretny czas podawany przez TrackBar1, np.: TrackBar1->Position = 1000, więc Sleep(1000) ... następnie polecenie.
Pod przycisk Stop wrzuciłem fragmentu kodu Barona odnośnie przerywania działania Application->ProcessMessages(); if(przerwij == true) break;
Problem jednak polega na tym, że polecenie Sleep ( lub pętla, nie mam 100% pewności ) zatrzymuje ingerencję w Form1 na czas jednego obrotu, a co za tym idzie każda ingerencja w przycisk, TrackBar1, czy nawet próba zamknięcia programu powoduje najpierw zakończenie przetwarzania ( pomimo instrukcji przerwania ). Nie ma kłopotu, gdy Sleep jest 100, ale przy 100000 zaczyna to być uporczywe :/
Ma ktoś może jakiś pomysł?
Oczywiście Sleep mogę ominąć, jeśli tylko ktoś podpowie jak inaczej zatrzymać wykonanie polecenia o wartość TrackBar1.
Próbowałem "obejść" problem i podzieliłem wartość TrackBar1 na 10, żeby utworzyć 10 Sleepów, ale to także nie pozwala na edycję Form1 podczas przeskakiwania między Sleep'ami.

Z góry dziękuję za podpowiedzi.

Pozdrawiam
Liberae sunt nostrae cogitationes
Avatar użytkownika
nvdante
Intelektryk
Intelektryk
 
Posty: 188
Dołączył(a): piątek, 12 czerwca 2009, 16:58
Lokalizacja: Dom
Podziękował : 8
Otrzymał podziękowań: 0
System operacyjny: Windows 7
Kompilator: VS 2015
Gadu Gadu: 0
    Windows 7Firefox

Re: Modyfikacja podczas działania Sleep'a

Nowy postprzez Cyfrowy Baron » niedziela, 29 stycznia 2012, 09:50

Funkcja Sleep wstrzymuje całą aplikację, a nie tylko pętlę. W pliku pomocy można przeczytać:

Plik pomocy Embarcadero RAD Studio 2010 napisał(a):Delay program execution for a specified number of milliseconds.

Sleep pauses program executions as specified by the milliseconds parameter. Under Windows, Sleep is just a link to the Sleep function in the API system.




nvdante napisał(a): jak inaczej zatrzymać wykonanie polecenia o wartość TrackBar1.


Jakiego polecenia? Opisz w sposób zrozumiały, co konkretnie próbujesz osiągnąć.



nvdante napisał(a):nawet próba zamknięcia programu powoduje najpierw zakończenie przetwarzania ( pomimo instrukcji przerwania ).


Nie rozumiem! Jakiego przetwarzania?
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4719
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: Modyfikacja podczas działania Sleep'a

Nowy postprzez nvdante » niedziela, 29 stycznia 2012, 11:22

Jeśli chodzi o polecenie to używam najpierw odczytania pozycji TrackBar1, a później chodzi o odpalenie MediaPlayer1, więc jak widzisz nic skomplikowanego. Dodam tylko, że nie chodzi tu o zmianę głośności, bo dane z TrackBar1 są interpretowane jako czas.
Pisząc "zakończenie przetwarzania" miałem na myśli konieczność zakończenia poleceń w pętli, która już się zaczęła.
Skoro Sleep zatrzymuje cały program to jak można inaczej nakazać programowi wykonanie danego polecenia z dokładnym opóźnieniem, ale korzystając z innej metody?
Dla przykładu przyjmijmy, że chcę wyświetlić w Label1 jakiś napis, ale chcę, aby stało się to po na przykład 10s po kliknięciu Start, a w tym czasie chcę nadal mieć możliwość przerwania tego oczekiwania.

Pozdrawiam
Liberae sunt nostrae cogitationes
Avatar użytkownika
nvdante
Intelektryk
Intelektryk
 
Posty: 188
Dołączył(a): piątek, 12 czerwca 2009, 16:58
Lokalizacja: Dom
Podziękował : 8
Otrzymał podziękowań: 0
System operacyjny: Windows 7
Kompilator: VS 2015
Gadu Gadu: 0
    Windows 7Firefox

Re: Modyfikacja podczas działania Sleep'a

Nowy postprzez polymorphism » niedziela, 29 stycznia 2012, 11:47

Funkcję Sleep możesz zamienić takim kodem:
KOD cpp:     UKRYJ  
clock_t wait_ms = ...; // czas wstrzymania
clock_t time_ms = clock();

while(!przerwij && clock() - time_ms < wait_ms)
{
        Application->ProcessMessages();
//      Sleep(1);  <--- odkomentuj to, jeśli pętla będzie zużywać za dużo mocy CPU
}
 
C++ Reference - opis wszystkich klas STL-a i funkcji C.

Za ten post autor polymorphism otrzymał podziękowanie od:
nvdante
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2157
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 19
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    Windows XPFirefox

Re: Modyfikacja podczas działania Sleep'a

Nowy postprzez nvdante » niedziela, 29 stycznia 2012, 11:57

Dokładnie o to mi chodzi. Podczas działania programu można na bieżąco zmieniać wszystko.
Jest jednak maleńki problem. Gdy klikam Stop to program zaczyna wariować i ostatecznie się zawiesza.
W sumie nie widzę powodu, kod jest taki:
KOD cpp:     UKRYJ  
bool przerwij = false;
void __fastcall TForm1::SpeedButton1Click(TObject *Sender)
{
przerwij = false;

for (int i=0; i<100000000; i++)
        {
        int x = TrackBar1->Position * 16.6666;
        clock_t wait_ms = x;
        clock_t time_ms = clock();

        while(!przerwij && clock() - time_ms < wait_ms)
        {
                Application->ProcessMessages();
        }
        MediaPlayer1->Open();
        MediaPlayer1->Play();
        }
}
//---------------------------------------------------------------------------

void __fastcall TForm1::SpeedButton2Click(TObject *Sender)
{
przerwij = true;
}
Liberae sunt nostrae cogitationes
Avatar użytkownika
nvdante
Intelektryk
Intelektryk
 
Posty: 188
Dołączył(a): piątek, 12 czerwca 2009, 16:58
Lokalizacja: Dom
Podziękował : 8
Otrzymał podziękowań: 0
System operacyjny: Windows 7
Kompilator: VS 2015
Gadu Gadu: 0
    Windows 7Firefox

Re: Modyfikacja podczas działania Sleep'a

Nowy postprzez Cyfrowy Baron » niedziela, 29 stycznia 2012, 12:08

Użyj obiektu Timer i tam odmierzaj czas.
W tym fragmencie kodu, który przedstawiłeś zmienna przerwij tylko wyłącza zegar, nie zatrzymuje pętli for. Pętla działa do końca.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4719
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: Modyfikacja podczas działania Sleep'a

Nowy postprzez nvdante » niedziela, 29 stycznia 2012, 12:41

Czy w takim razie powinienem przepisać całą pętlę do środka do:
KOD cpp:     UKRYJ  
while(!przerwij && clock() - time_ms < wait_ms)
        {
                Application->ProcessMessages();
        }


??
Liberae sunt nostrae cogitationes
Avatar użytkownika
nvdante
Intelektryk
Intelektryk
 
Posty: 188
Dołączył(a): piątek, 12 czerwca 2009, 16:58
Lokalizacja: Dom
Podziękował : 8
Otrzymał podziękowań: 0
System operacyjny: Windows 7
Kompilator: VS 2015
Gadu Gadu: 0
    Windows 7Firefox

Re: Modyfikacja podczas działania Sleep'a

Nowy postprzez Cyfrowy Baron » niedziela, 29 stycznia 2012, 13:15

Ja wciąż nie rozumiem co Ty próbujesz osiągnąć, ale jedno jest pewne jeżeli chcesz przerwać jedną z pętli w zależności od stanu zmiennej to powinieneś ją umieścić wewnątrz tej pętli z warunkiem, a to wewnątrz której to zależy od tego, którą pętle chcesz przerwać.

Przerwanie obydwu pętli:
KOD cpp:     UKRYJ  
bool przerwij = false;
void __fastcall TForm1::SpeedButton1Click(TObject *Sender)
{
przerwij = false;

for (int i=0; i<100000000; i++)
        {
        int x = TrackBar1->Position * 16.6666;
        clock_t wait_ms = x;
        clock_t time_ms = clock();

        while(clock() - time_ms < wait_ms)
        {
                Application->ProcessMessages();
                if( przerwij == true ) return;
        }
        MediaPlayer1->Open();
        MediaPlayer1->Play();
        }
}
//---------------------------------------------------------------------------

void __fastcall TForm1::SpeedButton2Click(TObject *Sender)
{
przerwij = true;
}

Za ten post autor Cyfrowy Baron otrzymał podziękowanie od:
nvdante
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4719
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: Modyfikacja podczas działania Sleep'a

Nowy postprzez nvdante » niedziela, 29 stycznia 2012, 13:25

Działa znakomicie, dokładnie o to mi chodziło.
Dalsza część kodu to już tylko działania matematyczne, z którymi sobie powinienem poradzić.
Jak zawsze dziękuję za pomoc Wam obu.

Pozdrawiam
Liberae sunt nostrae cogitationes
Avatar użytkownika
nvdante
Intelektryk
Intelektryk
 
Posty: 188
Dołączył(a): piątek, 12 czerwca 2009, 16:58
Lokalizacja: Dom
Podziękował : 8
Otrzymał podziękowań: 0
System operacyjny: Windows 7
Kompilator: VS 2015
Gadu Gadu: 0
    Windows 7Firefox

Re: Modyfikacja podczas działania Sleep'a

Nowy postprzez nvdante » niedziela, 29 stycznia 2012, 14:22

Jeszcze jedno pytanko.
Taki kod:
KOD cpp:     UKRYJ  
x = (60/TrackBar1->Position)*1000;

nie zawsze zwraca wartość bez liczb po przecinku. Nie chcę wyświetlać tej wartości tylko użyć ją dalej w programie, ale w taki sposób, żeby dane polecenie uruchomiło się po np.: 1583ms, a nie po 2000ms. Jak wymusić na programie dokładne wykonanie polecenia w zadanym czasie?
Liberae sunt nostrae cogitationes
Avatar użytkownika
nvdante
Intelektryk
Intelektryk
 
Posty: 188
Dołączył(a): piątek, 12 czerwca 2009, 16:58
Lokalizacja: Dom
Podziękował : 8
Otrzymał podziękowań: 0
System operacyjny: Windows 7
Kompilator: VS 2015
Gadu Gadu: 0
    Windows 7Firefox

Re: Modyfikacja podczas działania Sleep'a

Nowy postprzez polymorphism » niedziela, 29 stycznia 2012, 14:33

A ten trackbar w jakich jednostkach jest?

Tak czy siak, spróbuj w ten sposób wykonać obliczenia:
KOD cpp:     UKRYJ  
x = 60 * 1000 / TrackBar1->Position;

Od strony matematycznej różnica żadna, ale od programistycznej już jest.
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2157
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 19
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    Windows XPFirefox

Re: Modyfikacja podczas działania Sleep'a

Nowy postprzez nvdante » niedziela, 29 stycznia 2012, 14:50

Już miałem napisać, że jest źle, ale najwidoczniej sam coś zepsułem przy przepisywaniu ;)
Jest super, właśnie o to chodziło.
Jeszcze raz dzięki za pomoc.

Pozdrawiam
Liberae sunt nostrae cogitationes
Avatar użytkownika
nvdante
Intelektryk
Intelektryk
 
Posty: 188
Dołączył(a): piątek, 12 czerwca 2009, 16:58
Lokalizacja: Dom
Podziękował : 8
Otrzymał podziękowań: 0
System operacyjny: Windows 7
Kompilator: VS 2015
Gadu Gadu: 0
    Windows 7Firefox

Re: Modyfikacja podczas działania Sleep'a

Nowy postprzez nvdante » niedziela, 29 stycznia 2012, 19:23

Zastanawia mnie jeszcze jeden fakt.
Logicznie sprawdzając wyrażenie typu:
KOD cpp:     UKRYJ  
60 * 1000 / TrackBar1->Position


dla TrackBar1 = 60 powinno dać wartość 1000.
Skoro tak to dlaczego możliwe jest, aby gołym okiem, zapętlając wykonywanie polecenia co 1000ms zaobserwować przesunięcie, a dokładniej program wykonuje się z takimi wartościami sekundowymi:
0, 1, 2, 3, 4.1, 5.1, 6.1, 7.2, 8.2 ... itd
Z tego co widać program nie wykonuje się o dokładnej chwili tylko zmiennej.
Jakiś pomysł dlaczego i jak to poprawić?
Niby ułamki sekund są mało ważne, ale w przypadku takiego programu bardzo mi na tym zależy.

Pozdrawiam
Liberae sunt nostrae cogitationes
Avatar użytkownika
nvdante
Intelektryk
Intelektryk
 
Posty: 188
Dołączył(a): piątek, 12 czerwca 2009, 16:58
Lokalizacja: Dom
Podziękował : 8
Otrzymał podziękowań: 0
System operacyjny: Windows 7
Kompilator: VS 2015
Gadu Gadu: 0
    Windows 7Internet Explorer 9

Re: Modyfikacja podczas działania Sleep'a

Nowy postprzez Cyfrowy Baron » niedziela, 29 stycznia 2012, 20:37

Ale o co Tobie chodzi? O to, że zegar nie odlicza precyzyjnie sekund czy, że wizualizacja tych sekund nie wypada co zadany czas?!
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4719
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: Modyfikacja podczas działania Sleep'a

Nowy postprzez polymorphism » niedziela, 29 stycznia 2012, 22:54

(...) dlaczego możliwe jest, aby gołym okiem, zapętlając wykonywanie polecenia co 1000ms zaobserwować przesunięcie (...) ?

Ano dlatego, że ani Twój "sleep", ani pozostały kod nie wykonują się za każdym razem w takim samym czasie. System windows nie jest RTOS-em, więc nie oczekuj, że wszystko wykonuje się dokładnie co do mikrosekundy. Nawet zakładając, że pętla opóźniająca czeka dokładnie sekundę, to zważ, że jest jeszcze czas, który jest potrzebny do wykonania pozostałej części kodu zawartego w pętli.
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2157
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 19
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    Windows XPFirefox

Następna strona

  • Podobne tematy
    Odpowiedzi
    Wyświetlone
    Ostatni post

Powrót do Ogólne problemy z programowaniem

Kto przegląda forum

Użytkownicy przeglądający ten dział: Brak zalogowanych użytkowników i 23 gości