Skocz do zawartości

[Delphi] - Wątki, tabela watków problem z synchronizacją


Integer

Polecane posty

Witam. Przykład jest zrobiony na podstawie gotowca, chce opanować watki, ale ciągle czegoś brakuje.

 

W tym przypadku mam problem z synchronizacją błąd dostępu 6 i jak kliknę na wątek to się pokazuje jeden progresbar, który zaczyna naliczać i staje.

Bardzo proszę o jakieś nakierowanie albo wskazanie błędów, bo pewnie na jednym się nie skończy.

 

Jest moduł dodatkowy i forma główna. jesli dobrze wgrałem załacznik to jest tu komplet w Delphi2007.

Chodzi o to że sa trzy watki w tabeli i wyświetlaja swoje stany w progressach, jak kliknę na TListCheckBox i zaznaczę nr wątku fajką

to watek rusza, a jak odznaczę to wątek pauzuje.

Po zakończeniu w Memo wyświetla czas trwania wątku.

 

 

unit UGlowna;

interface

uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs, ComCtrls, Menus, StdCtrls, CheckLst, ExtCtrls;

type
 TMainForm = class(TForm)
   MainMenu1: TMainMenu;
   Wtkitrzy1: TMenuItem;
   WatkiStart: TMenuItem;
   ChLBox: TCheckListBox;
   ProgressBar1: TProgressBar;
   ProgressBar2: TProgressBar;
   ProgressBar3: TProgressBar;
   MInfo: TMemo;
   procedure WatkiStartClick(Sender: TObject);
   procedure ChLBoxClickCheck(Sender: TObject);
 private
   { Private declarations }
 public
   { Public declarations }
 end;


var
 MainForm: TMainForm;

implementation
Uses ULiczWatek;

var ListWatek: TRecTabLiczWatek;


{$R *.dfm}


procedure TMainForm.WatkiStartClick(Sender: TObject);
var IWat: Integer;
begin
 ListWatek.Count:= cThreadMax;
 for IWat:= 0 to ListWatek.Count-1 do
 begin
   ListWatek.tab[IWat]:= TLiczWatek.Create(IWat, True);
   ListWatek.tab[IWat].Priority:= tpNormal;
   ChLBox.Items.Add( IntToStr(IWat) );
 end;

end;

procedure TMainForm.ChLBoxClickCheck(Sender: TObject);
var IWat: Integer;
begin

 for IWat:= 0 to ListWatek.Count-1 do
 begin
   if ChLBox.Checked[IWat]
     then ListWatek.tab[IWat].Resume
     else ListWatek.tab[IWat].Suspend;
 end;

end;

end. ŚU1]ŃŹ()Ń()(]5MUŃąYŃ
ąĄ
Ńą(ą

Ńą()QĄ5()Ń(Q1]ŃŹąĄQQĄ(Ń(15%Ńźź]ŃŃą(
Ń%Ńźź9^Ń(QMŃ%Ń(QQŃ%Ń(ŃŃ(Ń(ą(5QŃĄMQ=(MĄ5(ŃŃ
ŃĄQŃŃMąQ(ŃŃŃ(((QQ1]ŃŹlQĄ5tQ1]ŃŹ(QIQ1]ŃŹ(ŃQQ1]ŃŹ(
%Ń(()(1Ń]Ń
ŃQIQ1]ŃŹ()ąŃŃ)UUą()Q1]ŃŹ()ŃŃQ1]ŃŹ
ŃĄQŃŃMąQ)(ĄŃ
ŃĄQźźŃŃŹŃŃźI(=QŃQźźiąźżŃ(=QŃ5QŃ((
ŃQźźAŃź(15(QMŃŃQ
)()ŃŃQ1]ŃŹŃ)(ĄŃ)()Q1]ŃŹ5QŃĄMQ=)(QQŃŃQ
(ĄQQŃQMŃ(55%ź1Ą%ŃQŃĄ
ŃŹ%ŃQŃĄQQŃ)()Q1]ŃŹMĄ5)(QA       Ą5
A  %ŃQMŃĄ
ŃŹAŃ
Ń)()Q1]ŃŹŃ)$%Ń)%]%Ń)((5
Ą1      
Ąm
Ńt(ŃĄI(ąM(($ŃźQĄ5ź((Mą((MĄMĄ5()(()

Link do komentarza
Udostępnij na innych stronach

Musze jeszcze dopieścić ale coś już działa

 

 procedure TLiczWatek.Execute;
var I: Integer;
var IWat: Integer;
begin

 {Odnalezenie komponentu na formularzu}
 TProgressBar(MainForm.FindComponent('ProgressBar'+IntToStr(FCounter+1))).Max:= FLiczMax;

 While not Terminated do
 begin
    {
    if MainForm.ChLBox.Checked[FCounter]
      then Resume
      else begin Suspend; Exit; end;
    }
    for I:= 0 to cThreadMax-1 do
    begin
       Inc(FLiczPos);
       Sleep(200);
       Synchronize( ShowMe );
    end;

 end;


end;

Link do komentarza
Udostępnij na innych stronach

Po pierwsze: w wątku nie możesz zmieniać właściwości komponentów - zrób to przez Synchronize.

Po drugie: nie rób pętli warunkowej, tylko nieskończoną. Jeżeli zatrzymasz wątek poprzez Suspend, procedura Execute nie będzie się dalej wykonywała aż do wznowienia przez Resume.

 

Napisz, co Ci jeszcze nie działa, to coś poradzimy.

Etharnion - 2D RPG

Szukam grafika chętnego do współpracy przy projekcie.

Link do komentarza
Udostępnij na innych stronach

petla warunkowa jest jak najbardziej sluszna. Poleganie na resume/suspend oraz reusing "zakonczonych" waskow prowadzi do wielu problemow, zwlaszcza u poczatkujacych programistow. Zeby daleko nie szukac obsluga zwolnienia pamieci przy zamykaniu aplikacji, oraz rozne wyskakujace wtedy AV.

Always Dark<br />u1_tt_logo.png banner-1.pngexFabula-banner.pngson_banner_ubersmall.jpg

Link do komentarza
Udostępnij na innych stronach

Witam ponownie, dzięki pomocy Force udało się opanować wątki w tabeli.

Teraz szlifuje efekt robienia skinów pulpitu w osobnych watkach w odstępie czasowym co 100msec.

 

Koncepcja jest taka:

1. uruchamiam główny watek inicjujący kolejne wątki w tabeli,

- czyli kolejno odpalam wątki na razie w pętli ograniczonej żeby sobie nie zawiesić systemu :):

 

 

 

procedure TGlwWatek.Execute;
var IWat: Integer;
begin

//  TThreadPriority = (tpIdle, tpLowest, tpLower, tpNormal, tpHigher, tpHighest, tpTimeCritical);
 ListWatek.cnt:= cThreadMax;

 for IWat:= 0 to ListWatek.cnt-1 do
 begin
   if Terminated then Exit;
   ListWatek.tab[IWat]:= TLiczWatek.Create(IWat, True);
   ListWatek.tab[IWat].Priority:= tpNormal;
   ListWatek.tab[IWat].Resume;
   Sleep(FTickStep);                 // FTickStep:= 100

   FLicz:= IWat;
   // Synchronize( ShowMe );
 end;

end;
izZaYHX]Z^X]NU][YY[YZ[]Y[^]BXH]X[[H]XX]NY[
[N^T[J[N[^JÓYH
N]XH[XYBXYXH]X[X[HXYXQX[[B[YR[XYNYP[[
[H[[+^ŹójZŹ\"jk\"3iźs6ŹdźŚhnwWŚj,z{zZaH[HM[H[H[M[H

[M[H[MH[H[

 

B) teraz są odstępy między wywołaniem kolejnych watków 100msec -

przynajmniej tak i efekt chciałem osiągnąć wprowadzając Sleep w procedure TGlwWatek.Execute;

ale czy odstęp faktyczny jest taki czy gdzieś popełniłem błąd?

Bo jest mi potrzebny idealnie równy odstęp.

 

Dzięki za zainteresowanie tematem

ale faktyczne czasy

Link do komentarza
Udostępnij na innych stronach

Zarchiwizowany

Ten temat jest archiwizowany i nie można dodawać nowych odpowiedzi.

×
×
  • Utwórz nowe...