Wątki i ich ręczna kasacja

0

Witam!
Chciałem się dowiedziec, jaka jest możliwośc ręcznego usuwania i NULL`owania zmiennych typu TThread (i pochodnych). Przy próbie wywołania metody Free, czy chocby Destroy, otrzymuję komunikat o "Nieprawidłowym dojściu do okna (6)", pomimo tego, iż przed wykonaniem zwolnienia, wątek zostaje zatrzymany (suspended). Jaki jest tego powód....?

Pozdrawiam

0

może trzeba by trochę poczytać o wątkach :> Do czego jest Terminate i Terminated oraz jak powinno wyglądać ciało procedury Execute. Dodatkowo o odwołaniu do VCLa i o Synchronize bo to tu na 99% jest problem.

A na koniec jeszcze http://msdn2.microsoft.com/en-us/library/ms686717.aspx

0

Bo nie ma zostać suspended (zapauzowany) tylko Terminated. Wtedy wątek musi skończyć wywołanie Execute (sam musi sprawdzać czy nie dano Terminate). Ty na niego czekasz WaitFor i dopiero usuwasz. Ogólny zarys będzie taki:

Program główny:

Watek.Terminate();
Watek.WaitFor();
Watek.Free();

Funkcja wykonania wątku:

while (not Terminated) do
  begin
  //...
  end;
0

@Misiekd: nie traktuj każdego, który o coś pyta, jak typowego newbie...

Wracając do tematu, pokomentowałem "zbędne" linie, do testów. Wywaliłem w całym kodzie odwołania do wątku, pozostawiłem jedynie jego tworzenie oraz zwalnianie. Patrząc na kod w Execute po raz n-ty, wreszcie zauważyłem, że niepotrzebnie ustawiłem: FreeOnTerminate na True. Dopiero po wycięciu tej linii, która gwarantowała mi jakoby zwalnianie wątku po przerwaniu, wszystko działa.
Dzięki za pomoc... :}

0
mordek napisał(a)

@Misiekd: nie traktuj każdego, który o coś pyta, jak typowego newbie...

jako nooba traktuję każdego, kto w ten sposób zadaje pytania...

Patrząc na kod w Execute po raz n-ty, wreszcie zauważyłem, że niepotrzebnie ustawiłem: FreeOnTerminate na True. Dopiero po wycięciu tej linii, która gwarantowała mi jakoby zwalnianie wątku po przerwaniu, wszystko działa.

jakoś nie wierzę, że to było przyczyną a fakt iż teraz działa może być złudny - pewnie wywali się gdzieś indziej w najmniej oczekiwanym momencie

0

Nawet gdy metoda Execute była pusta (zawierała tylko pętlę która wykonywała się do momentu przerwania), a w kodzie programu wątek, czy tez jego metody nie były nigdzie wywoływane, program nadal wywalał komunikaty o "Nieprawidłowym...", dopiero usunięcie linii z "FreeOnTerminate", dało pozytywny skutek, co jest całkiem logiczne.

Nie zmienia to faktu, iż wolałbyś, aby ludzie nie zadawali pytań - tych prostych, jak i tych trudnych.

0

Mały test - czysta aplikacja. Na formie 1 Label (lbl1) i 2 Buttony (btn1 i btn2), kod poniżej

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    btn1: TButton;
    lbl1: TLabel;
    btn2: TButton;
    procedure btn1Click(Sender: TObject);
    procedure btn2Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

uses
  Unit2;

var
  t: TTest;

procedure TForm1.btn1Click(Sender: TObject);
begin
  t := TTest.Create(False);
end;

procedure TForm1.btn2Click(Sender: TObject);
begin
  t.Terminate;
end;

end.

oraz unit z wątkiem (stworzony standardowo przez wybranie File->New->Other->Thread Object)

unit Unit2;

interface

uses
  Classes;

type
  TTest = class(TThread)
  private
    { Private declarations }
    i: Integer;
  protected
    procedure Execute; override;
    procedure Show;
  end;

implementation

uses
  Unit1,
  SysUtils;

procedure TTest.Execute;
begin
  FreeOnTerminate := True;
  i := 0;
  while not Terminated and (i < 1000) do
  begin
    Inc(i);
    Synchronize(Show);
    Sleep(10);
  end;
end;

procedure TTest.Show;
begin
  Form1.lbl1.Caption := IntToStr(i);
end;

end.

Działa tak jak powinien, tzn odlicza od 0 do 1000 i kończy działanie lub po naciśnięciu btn2. Nic się nie sypie, nie ma żadnych błędów.

Dalej uważam, że to ty coś spieprzyłeś i że błąd jest z twojej winy a nie przez FreeOnTerminate. Polecam poczytać http://rtfm.killfile.pl, w szczególności http://rtfm.killfile.pl/#lajza http://rtfm.killfile.pl/#precyzja oraz http://rtfm.killfile.pl/#precyzja1

i na koniec jeszcze

mordek napisał(a)

dopiero usunięcie linii z "FreeOnTerminate", dało pozytywny skutek, co jest całkiem logiczne.

wskaż tą wielką logikę, którą się kierowałeś

Nie zmienia to faktu, iż wolałbyś, aby ludzie nie zadawali pytań - tych prostych, jak i tych trudnych.

Ilość wizyt	77
Ilość postów	10 

nie masz podstaw aby oceniać mnie i moje wypowiedzi ani tego co bym wolał a czego nie.

dla mnie EOT

0

Oceniasz człowieka po ilości wizyt...? Przestań lol`owac.
Przeczytałeś w ogóle mój ostatni post....? Metoda Execute była pusta, a w programie wątek został tylko utworzony i zwolniony - przeze mnie, ręcznie, tak to trudno zrozumiec?
Gdy FreeOnTerminate było ustawione na True, wątek po Terminate już został zwolniony, a do tego ja sam zwalniałem go raz jeszcze.

Kod, który przytoczyłeś, znacząco się różni od tego o którym ciągle piszę. Teraz topic można zakończyc, bo dalsza dyskusja z tobą nie ma najmniejszego sensu.

P.S. na forum jestem od roku 2003, mimo iż konto zostało założone dopiero w 2005.

EDIT
"...różni od tego o którym ciągle piszę." - czytaj ze zrozumieniem na następny raz, może dobrze ci to zrobi....

Gdy FreeOnTerminate było ustawione na True, wątek po Terminate już został zwolniony, a do tego ja sam zwalniałem go raz jeszcze.
jak się nie wie co się robi to potem tak jest

Gdybym nie wiedział co robię, to nie znalazłbym tego błędu sam.

Nadal uważasz, że twoje zdanie jest najważniejsze i zawsze poprawne, więc pozostań w tym przekonaniu - najlepiej do końca życia...

1 użytkowników online, w tym zalogowanych: 0, gości: 1