25. februar 2009 - 14:09Der er
12 kommentarer og 1 løsning
Et ur i en tråd
Jeg har et lille ur til at køre på en form, men det er lige som om den hakker lidt i det når programmet arbejder på noget andet. Jeg kom så til at spekulere på om man kunne lave den funktion i en tråd for sig selv så det hakkeri blev minimeret. Jeg har aldrig prøvet at lave noget med en tråd, så jeg søger en step by step beskrivelse af hvordan jeg gør for at undgå at min app himler.
constructor tMyThrd.create(aForm:TForm1);//reintroduce; begin inherited create(true);//suspended freeOnTerminate:=true; fForm:=aForm; //Reference til form end;
procedure tMyThrd.execute;//override; begin while not terminated do begin klokken:=timeToStr(time); synchronize(notifyCurrentTime);//send til form sleep(500); end end;
procedure tMyThrd.notifyCurrentTime; //Til at sende til referencen begin fForm.notifyThrdClock end;
mbsnet> kan ikke lige få noget fornuftigt ud af det kode. Men det forbavser ikke mig :-)
Det optimale set med mine øjne ville være hvis man kunne lave en unit med en procedure man kalder med et formnavn og et controlnavn og så stod den unit og skrev et tidspunkt der hele tiden. Men det er måske utopi at tænke sig.
Jeg har i skrivende stund ikke kunne lokalisere Jens' timer her på sitet. Men da der er mange indlæg fra han skal jeg nok lede lidt længere.
hej. først og fremmest er det ikke i en unit, men i trådens klasse, at arbejdet gøres :)
Hvis du ønsker at flytte tråden til en ny unit, kan det let gøres. Jeg sendte ovenstående eksempel for at vise hvordan en tråd ret hurtigt "kan" bygges.
Det vigtigste for mig var, at vise, at tråde benytter en "execute" procedure, hvor man gør arbejdet. Derudover en "custom" constructor (som du kan ændre til at håndtere hvilke som helst typer man måtte ønske). Referencen "TForm1" kan også ændres til noget andet.
Hvis det ønskes, kan jeg lave et andet eksempel med 2 units, men jeg vil sige, at det kræver en smule åbenhed, at se lyset i forhold til tråde, og samtidig, at når man har prøvet det et par gange, er det ret let.
Jeg tror dog jeg har fået et ur til at køre i en tråd nu. Desværre ser det bare ud til at de overførsler jeg kører tager så meget kraft ud af maskinen at uret hakker alligevel.
Gad vide om man kan lave en måde at starte en given funktion op i en tråd for sig selv. Altså et eller andet med en generel ting der kan kaldes med navnet på en funktion/procedure som så køres i en tråd - det må kunne fjerne lidt af belastningen fra opdateringen af mit skærmbillede. Jeg har set nogle indlæg om bekymring om tilgang til samme data fra flere tråde, men det vil ikke være et problem her da det er en sekventiel indlæsning af filer en for en.
Men du må hellere smide et svar for dine hints der har hjulpet mig videre.
ok. Jeg tror der må være noget andet i dit program, som opbruger ressourcerne, og får uret til at hakke.. Det er sansynligvis dette, som bør flyttes til en tråd. Det med uret kan så løses, evt sammen med andre små-opgaver, ved at benytte en anden timer/tråd til disse. Ellers prøv at maile dit projekt til mig på pub_@mbsnet.dk (uden underscore)
Det er et ret stort projekt der kræver brug af en MySQL server og nogle Paradox tabeller med forretningsdata i så............
Men du har ret i at der er noget der tager resourcer - der overføres data fra Paradox tabeller til MySQL i rå mængder. Den ene tabel på MySQL indeholder ca. 9 millioner records så det tager lidt kræfter at finde ud af om den record jeg vil overføre er ny eller eksisterer :-)
(ny kan jeg pludselig ikke bruge FireFox her på Eksperten! - den vil ikke opdatere siden når jeg trykker på knappen)
Det var lige derfor jeg gerne vil eksperimentere lidt og finde ud af om der evt. er en måde hvor man kan kalde en eksisterende funktion så den starter for sig selv i en tråd. Jeg tror jeg har fundet noget, men det er lidt langhåret.
Ja, men det lyder som en forkert rækkefølge at gøre det i. Normalt indtastes funktionskaldene under "execute" på tråden, og i stedet for at køre funktionerne fra programmet, startes tråden... Når så tråden er afsluttet sendes data til form, eller gemmes på disk.
En tråd kan i øvrigt "fyres af", uden at have en reference på formen. Kræver nok lidt øvelse først, men gøres således:
with tMyThrd.create(argument) do begin resume end;
procedure TThreadClock.CallEvents; var H, M, S, MSec, pH, pM, pS: Word; begin DecodeTime(Time, H, M, S, MSec); DecodeTime(PrevTime, pH, pM, pS, MSec);
if Assigned(FOnSecond) then FOnSecond(Self);
if Assigned(FOnMinute) and (pS > S) then FOnMinute(Self);
if Assigned(FOnHour) and (pM > M) then FOnHour(Self);
PrevTime := Time; end;
constructor TThreadClock.Create(aDrawTo: TWinControl); begin Self.Create; DrawTo := aDrawTo; end;
destructor TThreadClock.Destroy; begin FPen.Free; FBitMap.Free; inherited; end;
procedure TThreadClock.DoDrawToScreen; var DC: HDC; begin if Assigned(FDrawTo) then begin DC := GetDC(FDrawTo.Handle); if DC <> 0 then BitBlt(DC, 0, 0, FBitMap.Width, FBitMap.Height, FBitMap.Canvas.Handle, 0, 0, SRCCOPY);
ReleaseDC(FDrawTo.Handle, DC); end; end;
procedure TThreadClock.SetDrawTo(const Value: TWinControl); begin if Assigned(FDrawTo) then FDrawTo.WindowProc := OldWndMethod;
begin with FBitMap.Canvas do begin Brush.Style := bsSolid; Brush.Color := ClkFaceColor; FillRect(ClipRect); end;
DrawMinSteps; end;
procedure TThreadClock.Execute; begin while not Terminated do begin Synchronize(CallEvents); TickerCall; Synchronize(DoDrawToScreen); Sleep(100); end; end;
function TThreadClock.GetHeight: Integer; begin Result := 100; if Assigned(FDrawTo) then Result := FDrawTo.Height; end;
function TThreadClock.GetWidth: Integer; begin Result := 100; if Assigned(FDrawTo) then Result := FDrawTo.Width; end;
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.