Właściwość Visible komponentu a funkcja w osobnym wątku.

dział ogólny

Właściwość Visible komponentu a funkcja w osobnym wątku.

Nowy postprzez markosik20 » poniedziałek, 18 sierpnia 2008, 10:23

No własnie, jak to się ma do rzeczy.
Odpalam wątek przy pomocy BeginThread i w funkcji tego wątku obsługuje inną funkcję która także jest wykorzystywana później ale już po zakończeniu wątku

Kod: Zaznacz cały
bool Obsluga_panelu_zasilacza_1 (void)
{

  if(OdczytADC(*"1")==0)
  {
  Form1->Panel_zas1->Visible = false;//Hide();
  Form1->Label_brak_modulu1->Visible = true;//Show();
  return false;
  //goto koniec;
  }
..............


I teraz tak, jeżeli próbuje odkrywać lub zakrywać Panel_zas1 przy pomocy jego właściwości (Visible) to niestety nie działa to poprawnie, natomiast jeżeli korzystam z funkcji Show() lub Hide() ...to teżnie działa :( . Narazie obszedłem problem w ten sposób że odpalam Timer i w jego przerwaniu obsługuje funkcję
Kod: Zaznacz cały
bool Obsluga_panelu_zasilacza_1 (void);
. Tylko nie wiem czy to jest dobry sposób.
Avatar użytkownika
markosik20
 
    NieznanyNieznana

Re: Właściwość Visible komponentu a funkcja w osobnym wątku.

Nowy postprzez wargo » poniedziałek, 18 sierpnia 2008, 10:27

Jeśli już napisałeś funkcjję to wywołaj ją bez bool i void.
Ale jesli dzięki timer działa to to może być bardzo dobry sposób.
Ale czy funkcję wywoływałeś???
Avatar użytkownika
wargo
Mądrosław
Mądrosław
 
Posty: 389
Dołączył(a): niedziela, 13 lipca 2008, 16:44
Podziękował : 12
Otrzymał podziękowań: 3
System operacyjny: Windows 7
Kompilator: C++ Builder 6 Personal
Gadu Gadu: 6259515
    NieznanyNieznana

Re: Właściwość Visible komponentu a funkcja w osobnym wątku.

Nowy postprzez markosik20 » poniedziałek, 18 sierpnia 2008, 10:47

wargo napisał(a):Jeśli już napisałeś funkcjję to wywołaj ją bez bool i void.


Niestety :(, nie działa. Funkcja jest wywoływana w wątku tak
Kod: Zaznacz cały
..........
Obsluga_panelu_zasilacza_1();
........


Zauważyłem pewną prawidłowść, jeżeli w wątku wywołam tę funkcję to później bez problemu wszystko działa. Problem w tym że przy uruchamianiu programu chcę żeby komponent który "wątek" odkrywa lub zakrywa był niewidoczny. Jeżeli na dzien dobry komponent ukryję to "wątek" już go nieodkryje, jeżeli "wątek" sam sobie go zakryje to także go odkryje :roll: .

Kod: Zaznacz cały
bool Obsluga_panelu_zasilacza_1 (void)
{

  if(OdczytADC(*"1")==0)
  {
  Form1->Panel_zas1->Visible = false;//Hide();
  Form1->Label_brak_modulu1->Visible = true;//Show();
  return false;
  }

  Form1->Panel_zas1->Visible = true;//Show();
  Form1->Label_brak_modulu1->Visible = false;//Hide();

  Form1->Button_on_off_zas1->Caption = Form1->adc.On_Off;

  if(Form1->adc.On_Off == "Wlacz")
  {
   ........
   return true;
  }
  else
  {
    ...............   
    return true;
  }

}
Avatar użytkownika
markosik20
 
    NieznanyNieznana

Re: Właściwość Visible komponentu a funkcja w osobnym wątku.

Nowy postprzez Cyfrowy Baron » poniedziałek, 18 sierpnia 2008, 10:48

Za mało danych, żeby powiedzieć coś więcej, ale spróbuj po każdym ukryciu i odkryciu obiektu wywołać odświeżenie aplikacji, np:

Kod: Zaznacz cały
bool Obsluga_panelu_zasilacza_1 (void)
{

  if(OdczytADC(*"1")==0)
  {
  Form1->Panel_zas1->Visible = false;//Hide();
  Form1->Label_brak_modulu1->Visible = true;//Show();
  Application->ProcessMessages(); // <-- tutaj następuje odświeżenie aplikacji
  return false;
  //goto koniec;
  }
..............
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
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
    NieznanyNieznana

Re: Właściwość Visible komponentu a funkcja w osobnym wątku.

Nowy postprzez markosik20 » poniedziałek, 18 sierpnia 2008, 10:52

Cyfrowy Baron napisał(a):................... spróbuj po każdym ukryciu i odkryciu obiektu wywołać odświeżenie aplikacji, np:



Niestety, nie skukuje :( . Tzn. odkryty komponent dosłowanie na chwilę się pojawi (mignie). Chyba jednak zostanę przy Timerze.
Avatar użytkownika
markosik20
 
    NieznanyNieznana

Re: Właściwość Visible komponentu a funkcja w osobnym wątku.

Nowy postprzez Cyfrowy Baron » poniedziałek, 18 sierpnia 2008, 11:01

Wątek działa cały czas, dopóki nie zostanie zatrzymany, jeżeli w jednym wątku umieszczasz najpierw instrukcję ukrywającą, a potem odkrywającą, to jest oczywiste, że obiekt zostanie najpierw ukryty a zaraz potem odkryty i taki pozostanie zgodnie z kolejnością wykonywania się instrukcji.

Kolejna sprawa, to wątek działa do zakończenia wszystkich zawartych w nim instrukcji, to nie Timer, czyli jeżeli raz wywołasz wątek zgodnie z podanym przykładem, to wykona on zawarte w nim instrukcji od początku do końca, ale po zakończeniu instrukcji nie powróci do początku funkcji, po prostu dalej będzie działał oczekując na nowe instrukcje, których nigdy nie otrzyma, gdyż funkcja tego nie przewiduje, dlatego Twój wątek wykonuje instrukcje tylko raz i nigdy nie powróci, żeby wykonać instrukcje ponownie.
Posługując się funkcją goto możesz zmusić wątek do powrotu na początek funkcji zawsze gdy dojdzie do końca:

Kod: Zaznacz cały
void Obsluga_panelu_zasilacza_1 (void)
{
  lab_1: // etykieta powrotu, na końcu jest dwukropek nie średnik 

  if(OdczytADC(*"1")==0)
  {
  Form1->Panel_zas1->Visible = false;//Hide();
  Form1->Label_brak_modulu1->Visible = true;//Show();
  return false;
  }

  Form1->Panel_zas1->Visible = true;//Show();
  Form1->Label_brak_modulu1->Visible = false;//Hide();

  Form1->Button_on_off_zas1->Caption = Form1->adc.On_Off;

  if(Form1->adc.On_Off == "Wlacz")
  {
   ........
  // return true; // return przerywa wykonywanie funkcji, wiec należy to usunąć
  }
  else
  {
    ...............   
  //  return true; // return przerywa wykonywanie funkcji, wiec należy to usunąć
  }
 
  goto lab_1; // powrót do początku, na końcu jest średnik
}


Tak skonstruowana funkcja będzie się wykonywać w nieskończoność, wiec powinna być wykonywana tylko w wątku, gdyż tylko zatrzymanie wątku może zatrzymać funkcję.

Powinieneś coś wiedzieć o funkcji return, otóż powoduje ona zawsze przerwanie wykonywania instrukcji, jeżeli więc umieścisz ją gdzieś w funkcji i nastąpi jej wywołanie, to dalsze instrukcje znajdujące się pod funkcją return nigdy nie zostaną wywołane, dlatego usunąłem je z funkcji, dobrze jest więc zmienić typ funkcji z BOOL na void, żeby nic nie zwracała.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
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
    NieznanyNieznana

Re: Właściwość Visible komponentu a funkcja w osobnym wątku.

Nowy postprzez kinio » poniedziałek, 18 sierpnia 2008, 11:01

Cześć!

Jeżeli Twój wątek korzysta z zasobów dzielonych z procesem macierzystym jakim jest aplikacja, obojętnie czy jest to funkcja, czy sama własność Visible jakiegoś komponentu, to konieczne jest zastosowanie synchronizacji. Ma to na celu zapewnienie że z danego zasobu w danym czasie będzie korzystać jeden wątek (nie proces, ponieważ procesy nie mają wspólnej przestrzeni adresowej).
Jeżeli korzystasz z klasy TThread to użyj funkcji void Synchronize(void (*f)()), która jako parametr przyjmuje wskaźnik do funkcji. Funkcja Synchronize wywołuje podaną funkcje w sposób bezpieczny, czyli zabezpiecza to o czym pisałem. Jeżeli natomiast nie korzystasz z klasy TThread, to jedynym rozwiązaniem jest tzw. ustawianie mutex-ów - to są flagi które są tak zrobione że tylko jeden wątek w danym czasie może mieć do nich dostęp. Ustawiasz taki semafor i w momencie kiedy inny wątek chce korzystać z określonego zasobu sprawdza ustawienie takiej flagi, jeżeli jest zezwolenie to wykonuje swoje operacje jeżeli nie, to wstrzymuje się do momentu opuszczenia semafora.

Żeby dokładniej Ci odpowiedzieć, to musisz podać bardziej szczegółowy opis z jakich komponentów/klas korzystasz, aby wiedzieć jak poprawnie poradzić sobie z synchronizacją.

P.S. To co napisałem, to napisałem, ale po kolejnym przeczytaniu Twojego postu nie wiem, co to znaczy że funkcje nie działają? Czy to oznacza że nie ma reakcji na tą funkcję i program się zachowuje jak by jej w ogóle nie wywoływał, czy może program generuje wyjątki?

A tak teraz widze, CB ma racje, jeżeli zaraz po sobie umieścisz funkcję ukrywającą a w następnej linii wyświetlającą, to jasne że efektu nie zobaczysz.
Jednak tak ja piszę, konieczna jest synchronizacja jeżeli odwołujesz się do zasobów współdzielonych!!, bo inaczej program czasami będzie działa poprawnie a czasem się wywali!!
If a machine is expected to be infallible, it cannot also be intelligent.
-- A.Turing
Avatar użytkownika
kinio
Homos antropiczny
Homos antropiczny
 
Posty: 67
Dołączył(a): poniedziałek, 14 lipca 2008, 08:51
Podziękował : 0
Otrzymał podziękowań: 0
    NieznanyNieznana

Re: Właściwość Visible komponentu a funkcja w osobnym wątku.

Nowy postprzez markosik20 » poniedziałek, 18 sierpnia 2008, 11:25

Cyfrowy Baron napisał(a):Wątek działa cały czas, dopóki nie zostanie zatrzymany...


Wątek jest uruchamiany przez reakcję użytkownika (Button) i ma za zadanie "przygotować" aplikację do działania (połączyć się z zewnętrznym urządzeniem, odczytać dane, aktywować komponenty typu Tedit, Tbutton, TLabel które zgrupowane są w TPanel). Do czasu kiedy wątek się nie zakończy (na końcu funkcji umieściłem dodatkowo ExitThread(GetExitCodeThread(Find_Device, NULL)); wszystko jest zablokowane i aktywna jest TYLKO funkcja int __fastcall Find_Device(Pointer Parameter) wywołana jako osobny wątek.


Cyfrowy Baron napisał(a):Powinieneś coś wiedzieć o funkcji return, otóż powoduje ona zawsze przerwanie wykonywania instrukcji, jeżeli więc umieścisz ją gdzieś w funkcji i nastąpi jej wywołanie, to dalsze instrukcje znajdujące się pod funkcją return nigdy nie zostaną wywołane...


I taki właśnie miałem zamiar, jeżeli nie są spełnione pewne elementy to należy zaraz "opuścić funkcję" bez wykonywania pozosałych instrukcji.
To wychodzenie z funkcji przez return to takie przyzwyczajenie z programowania mikokontrolerów gdzie funkcja nie miała prawa działać w nieskończoność (miała zrobić konkretną rzecz i miała się zakończyć czytaj: zwolnić RAM). I tutaj jest takie moje podejście, wywołuje funkcję w której zawarte instrukcje w zależności od spełnionych warunków będą wykonywane lub nie poczym funkcję "należy opuścić" zeby poźniej z niej skorzystać z nowymi danymi.

kinio napisał(a):..........Czy to oznacza że nie ma reakcji na tą funkcję i program się zachowuje jak by jej w ogóle nie wywoływał, czy może program generuje wyjątki?


Wątek funkcję widzi na pewno bo wywołanie funkcji OdczytADC(*"1"); to odczyt danych z urządzenia które odpowiada prawidłowo (migają diody) ;) .


Kod: Zaznacz cały
int __fastcall Find_Device(Pointer Parameter)
{

  String  odp = "*01Z_ZAS_ADR_EnSyst1\r\n";
  String  zap  = "01ZZLDN?\r\n";

  unsigned char czekanie_na_zgloszenie_urzadzenia;
  char *ptr;

   ..................

   Obsluga_panelu_zasilacza_1(); //żeby wątek się zakończył to ta funkcja też musi

..................
ExitThread(GetExitCodeThread(Find_Device, NULL));

return true;

wykryto:   

...........
      ExitThread(GetExitCodeThread(Find_Device, NULL));
      return true;

brak_urzadzenia:
  Close_Comm(hCommDev);
  Form1->SpeedButton1->Enabled=TRUE;
  Form1->ComboBox1->Enabled = TRUE;
  Form1->SpeedButton1->Caption = "Podłącz";
  Form1->StatusBar1->Panels->Items[1] ->Text = "Port COM nieaktywny";
  MessageBox(NULL,brak_urzadzenia,blad, MB_OK);
  ExitThread(GetExitCodeThread(Find_Device, NULL));
  return false;
}



PS: Właśnie sprawdzilem pewną zależność. Jak wątek jest cały czas aktywny to jest OK. Jeżeli tylko się zakończy wszystko co "się odkryło" znika :( .
Avatar użytkownika
markosik20
 
    NieznanyNieznana

Re: Właściwość Visible komponentu a funkcja w osobnym wątku.

Nowy postprzez Cyfrowy Baron » poniedziałek, 18 sierpnia 2008, 16:48

Opisałeś nieprecyzyjnie swój problem. Umieszczone fragmenty kodu niczego nie ułatwiają. Wspominałeś, że z pomocą Timer'a wszystko działa prawidłowo, co nasuwa mi podejrzenie, że próbujesz używać wątku jak zegara, a tymczasem wątek z Timer'em nie ma nic wspólnego. Timer w każdym cyklu zegara wykonuje zawarte w zdarzeniu OnTimer instrukcje, podczas gdy wątek wykonuje instrukcje zawarte w funkcji wątku tylko raz, działa jak każda funkcja, różnica polega jedynie na tym, że program może wykonywać kilka wątków (funkcji) jednocześnie, ale zasada wykonywania wątku jest taka sama jak zasada wykonywania się funkcji. Staram się to opisać w miarę prosto, zrozumiale.
Wydaje mi się, że Twój problem polega nie na tym co znajduje się w wątku, lecz w sposobie wywoływania wątku.

Wrócę jeszcze do Timer'a, otóż jak wspomniałem w każdym cyklu zegara (właściwość Interval) jest wykonywana cała instrukcja zawarta w zdarzeniu OnTimer, z wątkiem jest natomiast tak, że wykonuje on całą instrukcję zawartą w wątku od razu i tak kończy swoje działanie, tzn. wątek teoretycznie działa, ale ponieważ wykonał już wszystkie instrukcje to nie ma już nic do roboty.Jeżeli nie zawarłeś w wątku jakiejś pętli, która wykonuje się w nieskończoność, lub do osiągnięcia jakiejś wartości, a umieściłeś tylko zbiór instrukcji, które po kolei się wykonują do osiągnięcia końca, czyli przypomina to np. kliknięcie w Button (zdarzenie OnClick), jednokrotne wykonanie funkcji. Tak skonstruowany wątek nie będzie niczym sterował, ani na nic oczekiwał podczas działania, niezależnie od tego, czy jest czynny, czy nie. Zaznaczam to dlatego, że mam wrażenie iż tak właśnie skonstruowałeś swój wątek, lub oczekujesz, że będzie on działał podobnie do Timer'a.

Wątek jest uruchamiany przez reakcję użytkownika (Button) i ma za zadanie "przygotować" aplikację do działania (połączyć się z zewnętrznym urządzeniem, odczytać dane, aktywować komponenty typu Tedit, Tbutton, TLabel które zgrupowane są w TPanel).


Jeżeli wszystkie komponenty, którym zmieniasz właściwość Visible znajdują się na Panel'u, to nie trzeba zmieniać tej właściwości dla każdego z tych komponentów oddzielnie, wystarczy zmienić właściwość Visible dla Panel'u i zostanie ona automatycznie ustawiona na taką samą dla wszystkich komponentów znajdujących się na tym Panel'u.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
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
    NieznanyNieznana

Re: Właściwość Visible komponentu a funkcja w osobnym wątku.

Nowy postprzez markosik20 » poniedziałek, 18 sierpnia 2008, 20:53

Cyfrowy Baron napisał(a):......wątek wykonuje instrukcje zawarte w funkcji wątku tylko raz, działa jak każda funkcja, różnica polega jedynie na tym, że program może wykonywać kilka wątków (funkcji) jednocześnie, ale zasada wykonywania wątku jest taka sama jak zasada wykonywania się funkcji. ...


I właśnie tak mam stworzony wątek. Poprostu wykonuje instrukcje raz i "się zamyka". Wszystko po to żeby komponenty mogły być aktualizowane danymi jakie są uzyskiwane z portu COM uzrądzenia w czasie rzeczywistym. W wątku pracuje obsługa połączeń portu szeregowego i wszystkie dane są prawidłowo obliczane, aktualizowane i wyświetlane. Ostatnią intrukcją jaka jest w wątku to poprostu odpalenie Timera który za 500ms odkrywa odpowiednie grupy komonentów.
Jeżeli dobrze zrozumiełam to wątek wcale nie musi pracować w pętli nieskończonej?
Avatar użytkownika
markosik20
 
    NieznanyNieznana

Re: Właściwość Visible komponentu a funkcja w osobnym wątku.

Nowy postprzez Cyfrowy Baron » wtorek, 19 sierpnia 2008, 08:10

Musisz mieć gdzieś błąd w kodzie, ale nie w tych fragmentach, które zaprezentowałeś. Być może błąd tkwi w samej koncepcji mechanizmu, ale podałeś zbyt mało danych by można było coś stwierdzić.
Czy stosowanie wątku w tym programie jest czymś uzasadnione?
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
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
    NieznanyNieznana

Re: Właściwość Visible komponentu a funkcja w osobnym wątku.

Nowy postprzez markosik20 » wtorek, 19 sierpnia 2008, 12:10

Cyfrowy Baron napisał(a):Czy stosowanie wątku w tym programie jest czymś uzasadnione?


Głównie chodziło mi o odświerzanie danych w komponentach typu TEdit w czasie rzeczywistym (dane z portu szeregowego).
Avatar użytkownika
markosik20
 
    NieznanyNieznana

Re: Właściwość Visible komponentu a funkcja w osobnym wątku.

Nowy postprzez Cyfrowy Baron » wtorek, 19 sierpnia 2008, 14:00

No ale co ma z tym wspólnego wątek, dane w komponentach zostaną odświeżone dopiero gdy wywołasz jakąś funkcję, która to zrobi. Samo nic się nie zrobi, a użycie wątku jest tutaj zupełnie niejasne. Im więcej czytam o tym co robisz, tym większe odnoszę wrażenie, że nie wiesz czym tak na prawdę jest wątek i jak należy go stosować.

Wątek pozwala na działanie dwóch procesów jednocześnie, nawet nie uruchomienie. Takie procesy (tutaj funkcje) mogą działać niezależnie od siebie, ale są tylko funkcjami i niczym więcej, robią to samo co wszystkie funkcje, przez umieszczenie ich w wątku nie nadajesz im żadnych szczególnych właściwości.

Jeżeli wątek ma oczekiwać na jakieś dane i w zależności od otrzymanych wartości steruje jakimś obiektem, to taki wątek musi cały czas działać, nasłuchiwać w oczekiwaniu na jakieś wartości. Jeżeli go uruchomisz on wykona instrukcje zawarte w funkcji i się zakończy, to jak może odświeżać cokolwiek w czasie rzeczywistym skoro po wykonaniu instrukcji się zatrzymał.

Zaczynam się już gubić w tym twoim programie.

Ty chyba zamiast wątków powinieneś raczej zastosować przechwytywanie haków systemowych, wtedy po wystąpieniu jakiegoś zdarzenia, program mógłby podjąć odpowiednią operację. Coś jak keyloger, który nasłuchuje czy z klawiatury nadchodzą jakieś komunikaty (skrót myślowy) i jeżeli jakiś komunikat się pojawi to program podejmuje określone działanie, ale wątek tego na pewno nie potrafi.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
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
    NieznanyNieznana


  • 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 36 gości

cron