Avatar billede snowball Novice
30. juni 2000 - 14:36 Der er 13 kommentarer og
2 løsninger

Så vent dog !

Jeg er ved at lave på er program hvor jeg skal ha' vist en ny form mens den gamle laver noget i baggrunden. Det er heller ikke noget problem !

MEN, lige efter den nye form bli'r vist går den gamle i gang med en hel hel masse som ta'r faktisk alt CPU kraften. Det vil sige, at den nye form når ikke at blive tegnet færdig før den gamle begynder på det den skal lave.

Kan man ikke på en eller anden måde lægge en delay(1000); ind som man kan i go'e gamle C++, så den når at tegne hele formen med den rigtige baggrundsfarve og de 2 labels der er på den inden den anden form går videre med det den skal ???

Snowball
Avatar billede borrisholt Novice
30. juni 2000 - 14:45 #1
Snowball >> Tråde, tråde og atter tråde. Hvis du koede den tunge baggrunds process i en eller flere tråde var du ude over problemet.
Ellers kan du kalden en  refresh på din form der skal tegnes op fx. SplashScreen.Refresh;

Endelig var det nok værs at kigge på Application.ProcessMessages(); proceduren

jens B
Avatar billede lthrane Nybegynder
30. juni 2000 - 14:49 #2
f.eks.:  sleep(5000)
Avatar billede snowball Novice
30. juni 2000 - 14:57 #3
En .Refresh hist og her løst problemet ;)

Jeg er godt klar over at man kan lette arbejdet med tråde, men jeg er ikke lige helt med på hvordan man helt præcist kan dele det op !

Har du et godt eksempel på det ???

Snowball
Avatar billede dj Nybegynder
30. juni 2000 - 15:00 #4
jeg giver borisholt ret .. jeg tror dog du kan fixe det ligesom han sige ved at indsætte en application.processmessages; i dine loops hvor du udfører det meget processorkrævende arbejde.

Ilthrane: sleep er ikke nogen god løsning da det processorkrævende arbejde stadig skal ekserveres på et eller andet tidspunkt, og så vil det bare blokere for programmet i på et senere tidsrum .. derfor er processmessages en langt bedre løsning ..

Det var alt herfra :)

_DJ_
Avatar billede lthrane Nybegynder
30. juni 2000 - 15:04 #5
>>>dj
Jeg er enig med dig i at sleep() stinker, og man bør løse opgaven på anden vis.

Men snowball efterlyste funktionen i sit indlæg, så jeg ville lige nævne den.

god weekend...
Avatar billede dj Nybegynder
30. juni 2000 - 15:05 #6
Der ligger et eksempel med i delphi under ..\Borland\Delphi5\Demos\Threads den kan vise dig hvordan man bruger tråde/threads.

Dog vil jeg anbefale dig at afprøve processmessages først for jeg er ret sikker på at det vil virke ganske glimrende i dit tilfælde, husk dog på at du skal indsætte application.processmessages; hver gang der er et loop af en eller anden slags .. FOR/While etc. i den kode som er meget processorkrævende.

Nåh.. tilbage til Diablo II ses på b.net :)
Avatar billede dj Nybegynder
30. juni 2000 - 15:06 #7
lthrane: OK, og god weekend selv :)
Avatar billede borrisholt Novice
30. juni 2000 - 15:08 #8
Tråd eksemplet i Delphi Stinker. De balnder en masse ting ind i det som ikke har noget med sagen at gøre ... Jeg har et simplet eksemple, hvis nogen ønsker det så send en mail til mig

Jens@Borrisholt.com

Jens B
Avatar billede snowball Novice
30. juni 2000 - 15:09 #9
.Refresh løst så'n set "opgaven" men jeg ta'r da lige en kigger på det andet, så jeg kan bruge det næste gang ;)

Go' weekend (og drik nu ikke for meget) ;)

Snowball
Avatar billede dj Nybegynder
30. juni 2000 - 15:26 #10
borrisholt: jeg kunne da godt tænke mig at se dit eksempel ..

du can bare sende den til coding@sguft.com
Avatar billede lrj Nybegynder
30. juni 2000 - 20:36 #11
application.processmessages skal man passe MEGET på, hvis man ikke har helt styr på hvad det gør - det kan nemlig give seriøse problemer. Brugeren kan fx. finde på at trykke på en knap som udfører det kode som du allerede er i gang med at udføre - POW, dødt program.

application.processmessages er fint nok i starten, men det holder ikke i længden. Belært af programmøren bag ICS (http://www.rtfm.be/fpiette/indexuk.htm), så er asynkron programmering meget mere effektiv end tråde. Jeg er i hvert fald holdt op med at bruge tråde.
Avatar billede dj Nybegynder
30. juni 2000 - 20:52 #12
lrj>> Du har ret, i dit eksempel kan det jo dog fixes ved at disable knappen og enable den til slut i koden igen, men det gælder jo selvfølgelig ikke altid ... fordelen ved processmessages er jo bare at det er en simpel løsning der som regel også virker til de fleste knapt så avancerede formål.

Men asynkron programmering lyder da ret spændende, er det noget som du ville have noget imod at forklare en lille smule om, altså hvad der gør det bedre end tråde ? Og har du evt. noget eksempelkode til at ligge som man kan se hvordan man skal bruge det udfra ?
Avatar billede lrj Nybegynder
01. juli 2000 - 00:40 #13
Jeg tror faktisk ICS er det aller bedste eksempel.

Men det handler om at du du laver et objekt som har sin egen messagepump - ligesom application har det. Det er jo den du beder om at tømme sin kø når du kalder processmessages.

Normalt laver jeg et objekt som nedarver fra TComponent og som jeg så giver en public variabel af typen: FHandle: HWND; Desuden laver jeg en metode kaldet procedure WndProc(var MsgRec: TMessage); - det er den der er messagepumpen for objektet. Indholdet af denne procedure ses nedenfor.

I objektets create skriver jeg så:
inherited create(AOwner);
FHandle := AllocateHWnd(WndProc);

Og i destroy bliver det så:
DeallocateHWnd(FHandle);

Herefter skal du så have defineret hvilke messages dit objekt skal reagere på. Jeg har fx. defineret en metode kaldet procedure WMAutoDisconnectUser(var msg: TMessage); message WM_AUTODISCONNECT; - den hører til WM_AUTODISCONNECT, som jeg har defineret som Type WM_AUTODISCONNECT = WM_APP + 1;

Proceduren WMAutoDisconnectUser er defineret som:
procedure TISPConControl.WMAutoDisconnectUser(var msg: TMessage);
begin
...blah - gør noget med den vedsendte TMessage - her trækker jeg en henvisning til et objekt (pas forresten på med det, når det er asynkront. Er objektet gået ud af scope virker det ikke længere, og programmet dør...)
  assert(TObject(msg.WParam) is TOnlineUser);
...blah
end;

Og her følger min WndProc så:

procedure TISPConControl.WndProc(var MsgRec: TMessage);
begin
  with MsgRec do
  begin
    case Msg of
      WM_AUTODISCONNECT: WMAutoDisconnectUser(MsgRec);
    else
      Result := DefWindowProc(Handle, Msg, wParam, lParam);
    end;
  end;
end;

Og det den gør: hvis ikke det er en message som objektet skal håndtere, kaldes standard-handleren. Dette bør man altid gøre, med mindre man har en MEGET god grund til ikke at gøre det.


Når du så vil kalde den asynkrone metode bruger du så:

PostMessage(ConnControl.Handle, WM_AUTODISCONNECT, integer(self), 0);

her er ConnControl.Handle så en henvisning til det HWND vi definerede i interfacet og skabte i constructoren. WM_AUTODISCONNECT er typen af message, og de sidste to parametre er valgfrie integer værdier. Her er det en objektreference til et objekt jeg *VED* ikke går ud af scope.


Håber det hjalp. Og hvis du har lyst kan du såmædt sagtens se hele sourcen, men det er lidt af et monster af et program, sådan lige at sætte sig ind i :) (stofanet trafik/tids måling for flere brugere samt autosignon...) Det er GPL, så sourcen er frit tilgængeligt.

Right, det er vist nok for nu..
Avatar billede snowball Novice
01. juli 2000 - 00:53 #14
Nu er jeg godt nok stået af ;)

Det fattede jeg ikke ret meget af *GG*

Snowball
Avatar billede lrj Nybegynder
01. juli 2000 - 01:14 #15
Æv, jeg synes ellers det var ganske omfattende.

Prøv at læse det igen, langsommere. Det er lidt tungt første gang, så det skal ikke kun skimmes. Spørg hvis der er noget der er uklart formuleret. Så skal jeg nok træde til.
Avatar billede Ny bruger Nybegynder

Din løsning...

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.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester

IT-JOB

Forsvarsministeriets Materiel- og Indkøbsstyrelse

Cyberdivisionen søger IT-metodespecialist og projektkoordinator i Ballerup

Capgemini Danmark A/S

Client Partner

Riskpoint A/S (Riskpoint Solutions Limited)

Senior Developer