logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

Delphi CreateThread – jak sprawdzić i zakończyć działający wątek?

pawel2006 19 Mar 2006 10:14 1974 5
REKLAMA
  • #1 2431505
    pawel2006
    Poziom 2  
    Posty: 4
    Mam urucomiony watek i to działa bez problem wygląda tak
    procedure TForm1.BitBtn5Click(Sender: TObject);
    var
    hThread: THandle;
    THreadID: DWord;
    // Dane: PDane;
    begin
    { hThread:= CreateThread(nil,
    0,
    @ThreadFunc, // Adres procedury dla wątku
    nil, // Rekord z danymi dla wątku
    0,
    THreadID);
    if hThread = 0 then
    MessageBox(Handle, 'Nie udało się utworzyć wątku', nil, MB_OK);
    }
    end;
    function THreadFunc(P: pointer): LongInt; stdcall;
    begin
    ......

    end;

    problem mam taki
    nie wiem jak przerwać uruchomiony wątek

    i jak sprawdzic czy wątek jest uruchomiony i go zamknąć
    Prosze o pomoc :cry:
  • REKLAMA
  • Pomocny post
    #2 2431755
    Akane
    Poziom 27  
    Posty: 638
    Pomógł: 144
    Ocena: 33
    WaitForSingleObject(hThread, max_milisekund) zwraca:
    WAIT_ABANDONED - dla mutexa, pomijam
    WAIT_OBJECT_0 - coś się stało, np thread juz zakończył
    WAIT_TIMEOUT - thread nadal działa
    WAIT_FAILED - zapytaj w GetLastError()

    zabicie threadu (brutalne):
    if GetExitCodeThread(hThread, &code)
    TerminateThread(hThread, code);

    lepszy sposób: SuspendThread, GetThreadContext, zmień EIP na adres api ExitThread, SetThreadContext, ResumeThread
    Zadziała tak jakby thread sam wykonał ExitThread
  • REKLAMA
  • Pomocny post
    #3 2431804
    notset
    Poziom 17  
    Posty: 177
    Pomógł: 24
    Ocena: 5
    hThread sobie wrzuc do zmiennych globalnych jesli jest tworzony tylko jeden watek w danym momencie.. i wtedy w dowolnym miejsci bedziesz mogl zrobic np. TerminateThread(hThread, 0); Aby w jakims miejscu poczekac na zamkniecie watku jest api WaitForSingleObject wiecej poczytaj na MSDN'ie.

    Ale widze ze piszesz to w Delphi a tam sa gotowe klasy dla Watkow ktore sie bardzo przyjemnie obsluguje.. np.

    Delkarujesz typ klasy:

    TMyThread = class(TThread)
    procedure Execute; orerride;
    end;

    Kursor ustaw na linijce z "procedure" i kliklij CRTL+SHIFT+C

    pojawi sie metoda:

    procedure TMyThread.Execute;
    begin
    // tutaj wstawiasz to co ma sie wykonac w watku
    end;

    Wywolujesz to tak:

    var
    MyThread: TMyThread;
    begin
    MyThread := TMyThread.Create(False); // juz tutaj zostanie odpalony watek
    end;

    Lub:

    var
    MyThread: TMyThread;
    begin
    MyThread := TMyThread.Create(True);
    MyThread.FreeOnTerminate := True;
    MyThread.Resume; // tutaj zostanie odpalony watek
    end;

    Jesli w procedurze watku Execute bedziesz chcial korzystac z danych na formularzu itp. to pamietaj zeby to robic synchronicznie, wtedy delkarujesz np tak:

    TMyThread = class(TThread)
    Tekst: String;
    procedure GetTextFromForm;
    procedure Execute; orerride;
    end;

    teraz:

    procedure TMyThread.GetTextFromForm;
    begin
    Tekst := Form1.Edit1.Text;
    end;

    procedure TMyThread.Execute;
    begin
    Synchronize(GetTextFromForm);
    // tutaj np. wstawiasz operacje na zmiennej Tekst
    end;


    Chodzi o to zeby sie watek formularza i nasz watek zsynchronizowal poniewaz jak tego nie bedzie to raz bedzie dzialac a raz nie.. o konsekwencjach nie musze pisac :)

    Pozdrawiam
  • REKLAMA
  • #4 2432029
    pawel2006
    Poziom 2  
    Posty: 4
    Działa ok
    a jak można zrobic np uruchomic wątek
    i jesli wątek nie ukończy się przed czasem np 10 sek dać komunikat
    i w którym miejscu to umieścić
  • REKLAMA
  • Pomocny post
    #5 2432096
    Akane
    Poziom 27  
    Posty: 638
    Pomógł: 144
    Ocena: 33
    Sposobów jest tyle ile programistów:)
    Najprostszy:
    Zaraz po CreateThread zapamiętaj gdzieś hThread - w globalnej zmiennej, w klasie, albo w property okienka (SetProp)...
    i uruchom timer 10000ms.

    W OnTimer już wiesz co zrobić:
    1. if thread_dziala() then terminate()
    2. wyłącz timer i wyzeruj hThread

    W przypadku gdyby thread zakończył przed czasem - możnaby dodać do zmiennych wątku ID timera który go szpieguje i wyłączyć ten timer zanim naturalnie zakończysz thread
  • #6 2433042
    pawel2006
    Poziom 2  
    Posty: 4
    Działa. Wielkie dzięki
REKLAMA