AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Problem mit Delay

Ein Thema von PaKir · begonnen am 10. Mär 2005 · letzter Beitrag vom 19. Feb 2008
Antwort Antwort
Seite 3 von 3     123   
v2afrank

Registriert seit: 9. Mai 2005
Ort: Bocholt
573 Beiträge
 
Delphi XE2 Professional
 
#21

Re: Problem mit Delay

  Alt 18. Feb 2008, 13:30
Du hast mich ja schon überzeugt. Ich habe hier einen Thread benutzt, der eine serielle Schnittstelle abpollt.
Ich bin gerade dabei das das ganze mit Hilfe der Cportlibary ereignisbasiert zu gestalten
  Mit Zitat antworten Zitat
Benutzerbild von sirius
sirius

Registriert seit: 3. Jan 2007
Ort: Dresden
3.443 Beiträge
 
Delphi 7 Enterprise
 
#22

Re: Problem mit Delay

  Alt 18. Feb 2008, 13:40
Zitat von v2afrank:
Du hast mich ja schon überzeugt. Ich habe hier einen Thread benutzt, der eine serielle Schnittstelle abpollt.
Ich bin gerade dabei das das ganze mit Hilfe der Cportlibary ereignisbasiert zu gestalten
In einem Thread ist es tödlich auf Application zuzugreifen. Da solltest du schon auf deine eigene Messageverarbeitung im Thread zurückgreifen, was auch bei weitem sinnvoller ist. Und wenn im Thread keine Messages abgearbeitet werden, dann ist es durchaus legitim (im Thread) sleep zu benutzen. Aber mit Abstand besser ist es natürlich mit Ereignissen zu arbeiten.
Dieser Beitrag ist für Jugendliche unter 18 Jahren nicht geeignet.
  Mit Zitat antworten Zitat
Benutzerbild von negaH
negaH

Registriert seit: 25. Jun 2003
Ort: Thüringen
2.950 Beiträge
 
#23

Re: Problem mit Delay

  Alt 18. Feb 2008, 13:53
Wenn du in einem Thread warten möchtest dann benutze WaitForMultipleObjects(). In WFMO() speicherst du bei Events ein Array auf deine Eventhandles ab und als Timeout setzt du meistens INFINITE. So wird der Thread gezielt schlafen gelegt und Windows weckt diesen bei einem Event auf. Da die RS232 Schnittstellen, vom Windows-API aus betrachtet, sowieso Eventbasiert sind und Overlapped arbeiten können, ist diese Vorgehensweise die Beste. Neben den Events die du für die Overlapped-Results und RS232 benötigst (WaitCommEvent usw.) kannst du zusätzlich nun auch Events anlegen die du zb. extern ausserhalb des Threadobjektes auf sichere Weise auslösen kannst. Zb. ein Terminierungsevent beim Zerstören des Threadobjekts ist so ein Fall. Du signalisierst dort ein Event, zb. EventThreadTerminate das im Array der Events von WaitForMultipleObjects enthalten ist. Wartet der Thread nun an dieser Stelle so löst das signalisierte Event die Rückkehr aus dieser WFMO() Funktion aus. Als Resultat bekommst du vom Windows mitgeteilt das es das ThreadTerminateEvent, also der Index in das Events Array, was das signalisierte. In einer nachfolgenden CASE Abfrage dieses Resultates kannst du also dann gezielt das Event zurücksetzen und die Threadproc verlassen. Auf Mainthread-Seite wird nach dem signalisieren mit ThreadTerminateEvent selber nun mit MsgWaitForMultipleObjects() und dem TThread.Handle auf diesen gewartet. Also erst wenn der Thread auf ThreadTerminateEvent reagiert hat und seine ThreadProc verlassen hat kehrt die Prozedur im MainThread zurück. So hat man sauber und ohne Rechenzeitverschwendung einen Thread terminiert.

Gruß Hagen

EDIT: au mann, meine Tippfehler sind immer wieder nervend. Scheiß M$-Keyboard.
  Mit Zitat antworten Zitat
Landfloh

Registriert seit: 17. Feb 2008
75 Beiträge
 
Delphi 7 Personal
 
#24

Re: Problem mit Delay

  Alt 18. Feb 2008, 14:20
Probiere mal sleep (...). In die Klammer die Millisecunden
  Mit Zitat antworten Zitat
mkinzler
(Moderator)

Registriert seit: 9. Dez 2005
Ort: Heilbronn
39.858 Beiträge
 
Delphi 11 Alexandria
 
#25

Re: Problem mit Delay

  Alt 18. Feb 2008, 14:25
Vergesse Sleep() besser
Markus Kinzler
  Mit Zitat antworten Zitat
bluesbear

Registriert seit: 14. Dez 2005
Ort: Hahnstätten
355 Beiträge
 
Delphi 2007 Enterprise
 
#26

Re: Problem mit Delay

  Alt 18. Feb 2008, 14:32
Zitat von negaH:
(...)
Aber beide machen im Grunde einen Denkfehler denn sie handeln sich mit dem nun alternativen Pfad der Messageabarbeitung durch ein nicht mehr zentralisiertes Aufrufen von Application.ProcessMessages an anderer und erstmal unsichtbarer Stelle übelste Fehler ein. Dann kommt irgendwan eine Anfrage hier in der DP warum ihre Anwendung beim Beenden ständige Exceptions auslösst die final in einem RunTime Errror endet. (...)
Danke für diese nachvollziehbare Erläuterung!
Klaus M. Hoffmann
  Mit Zitat antworten Zitat
Benutzerbild von negaH
negaH

Registriert seit: 25. Jun 2003
Ort: Thüringen
2.950 Beiträge
 
#27

Re: Problem mit Delay

  Alt 18. Feb 2008, 15:52
@bluesbear:
Jo keine Ursache, ich als Borland Entwickler hätte Application.ProcessMessages und Konsorten von vornherein als private, nja vieleicht protected deklariert. Der Aufruf von Application.ProcessMessages an nicht zentralisierter Stelle, nämlich in Application.Run; ist immer gefährlich. Meistens möchte man nur mal die Darstellung des GUI's auffrischen, dann sollte mit TControl.Update gearbeitet werden, zb. TForm.Update oder RedrawWindow(Self.Handle, 0, RDW_UPADTENOW or RDW_ALLCHILDREN or RDW_INVALIDATE or RDW_NOERASEBKGND) oder mit einer eigenen Iteration über TForm.Controls[]. Alles andere, also zeitverzögerte Ausführungen dann per TTimer, soweit die grobe Auflösung von >= 20ms ausreichend ist. Braucht man es genauer bietet sich der Multimedia Timer an, Threads helfen kaum bei diesem Problem. Ein MMTimer hat aber erhöhte Anforderungen zb. das die aufgerufene Funktion nicht zu lange dauert und sich quasi "überschlägt" und wie eine Threadprocedure zu behandeln ist, sprich Vorsicht beim Zugriff auf globale Variablen und deren darin gespeicherten nicht-threadsicheren Objekten wie zb. TApplication. Threads selber sollten nach Möglichkeit keine Messagebearbeitungen machen. Das ist auch ein Sicherheitsrisiko, ähnlich wie Dienste/Services mit GUI.

Hält man sich nicht an solche Regeln dann bekommt man die bekannten Probleme die uns selber bei anderen Produkten ständig nerven. Man schiebt eine CD-ROM ein und greift dummerweise mit dem Windows-Explorer auf eine Netzwerkumgebung zu. Und bums blockieren sich beide blockierenden Aktionen gegenseitig, weil sie selber pollen. Denkt man das der Taskmanager das Problem beheben könnte irrt man sich meistens da auch dieser über das FileSystem geblockt wird und schwups hat man die miese Lage noch verschlimmbessert. Möchte man nun den Lock durch de CD-ROM Routinen beseitigen, indem man denkt man könnte das CR.ROM Fach hardwaremäßig per Schalter öffnen, so irrt man sich erneut. Entweder geht das garnicht weil der Windows-Explorer dies ebenfalls blockiert oder es geht und dafür streikt der Windows-Explorer noch mehr. Im schmlimmsten Fall fordert er einen auf die CR-ROM umgehend wieder einzulegen, damit die sich gegenseitig blockierende Situation auch ja wieder hergestellt wird. All das sind die Konsequenzen von einer asynchronen Verarbeitung bei der man über Blocking und Polling arbeitet.

Dann nerven diese Programme wie Kyodai Mahjong, die schönste DirectX Animationen benutzen und per Sleep() oder Delay() diese Animationen animieren. Das sich daraus eine 100% CPU Auslastung ergibt, mein Lüfter im Laptop quasi wie ein Hellikopter versucht gen Himmel zu fliegen ich das Ding an den Tisch nageln muß weil es sonst Richtung Küche fliegt und meine Bluetot-Strecke versagt, ist dem Programmierer nicht bewusst.

Dann diese Programme die eben mit einem alternativen Aufruf von Application.ProcessMessages wichtige Funktionen aus Appliction.Run deaktivieren. Das führt dann dazu das hinter dem Mainform dieser Anwendung, was natürlich sicherheitshalber vom Programmierer erstmal gesperrt wurde (DisableTaskWindows), ein Dialog hochpoppt, maybe eine Exception. Nun versuche mal an diesen Dialog ranzukommen wenn man ihn erstens nicht sieht und zweitens das davorliegende disabled Form nicht verschieben kann. Da der Dialog selber aber auch einen alternativen Application.ProcessMessage Pfad aufmacht -> nennt sich modale Dialogfunktion, blockiert sich nun das Delay() mit dieser Dialogfunktion. Gibts nur noch den Geheimtrick mit der ESCAPE Taste falls der Programmierer so schlau war und keinen Superduper Spezial Dialog ohne Titelleiste und somit Systemmenu erzeugt hat, und man noch die Zeit hat bis irgendeine andere Anwendung den Fokus vom Dialog zieht.

Ach ich hab wirklich Microsoft lieb gewonnen als es die Funktion in der Taskleiste vorgesehen hat das man beim mehrmaligen Schließen einer Anwendung diese abspachteln kann.

Gruß Hagen
  Mit Zitat antworten Zitat
shmia

Registriert seit: 2. Mär 2004
5.508 Beiträge
 
Delphi 5 Professional
 
#28

Re: Problem mit Delay

  Alt 19. Feb 2008, 16:20
Zitat von Xong:
Nimm das, Schurke!
Delphi-Quellcode:
procedure Delay(Milliseconds: Cardinal);
var
  Tick: Cardinal;
  Event: THandle;
begin
  Event := CreateEvent(nil, False, False, nil);
  try
    Tick := Milliseconds;
    // Milliseconds wird missbraucht als Zwischenspeicher für GetTickcount
    Milliseconds := GetTickcount;
    Tick := Tick + Milliseconds;

    while (Tick > Milliseconds) and
          (MsgWaitForMultipleObjects(1, Event, False, Tick-Milliseconds, QS_ALLINPUT) <> WAIT_TIMEOUT) do
    begin
      Application.ProcessMessages;
      Milliseconds := GetTickcount;
    end;
  finally
    CloseHandle(Event);
  end;
end;
Vorteil: Es wird nur mit VZ-losen Werten gerechnet.
Achtung da versteckt sich ein gemeiner Bug!!!
Angenommen GetTickCount liefert $FFFFF00. Es soll 1000 ms gewartet werden.
Also ist der Zielwert = $FFFFF00 + 1000 = (Taschenrechner her!) $000002E8
Nun wird die Bedingung in der While-Schleife die nächsten ~ 49 Tage nicht mehr True werden.
Die Wahrscheinlichkeit ist gering, dass dieser Bug auftritt.
Falls aber doch hängt das Programm.
Andreas
  Mit Zitat antworten Zitat
Benutzerbild von negaH
negaH

Registriert seit: 25. Jun 2003
Ort: Thüringen
2.950 Beiträge
 
#29

Re: Problem mit Delay

  Alt 19. Feb 2008, 17:53
gibt es diesen Bug auch mit mener Funktion, gleich am Anfang dieses Threads ?

Gruß Hagen
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 3 von 3     123   


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 05:05 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz