AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Win32/Win64 API (native code) Delphi Überlappendes Application. ProcessMessages macht Unsinn
Thema durchsuchen
Ansicht
Themen-Optionen

Überlappendes Application. ProcessMessages macht Unsinn

Ein Thema von Proddi · begonnen am 24. Feb 2004 · letzter Beitrag vom 27. Feb 2004
Antwort Antwort
Proddi

Registriert seit: 4. Sep 2003
9 Beiträge
 
#1

Überlappendes Application. ProcessMessages macht Unsinn

  Alt 24. Feb 2004, 21:12
Ich habe folgenden Code:

mit WaitForRequest wird ein Wert (über TCP) angefordert, ReqUID ist ein Objekt. Eine Schreibroutine,welches die ReqUID füllt funktioniert ebenfalls.
ReqUID ist ein Item aus einer Liste, wenn mehrere Anforderungen zur gleichen Zeit erfolgen. Der ermittelte Wert wird dann in das UID-Obkelt geschrieben, welches am längsten auf den Wert wartet.

Klappt soweit alles bis auf folgendes Szenario:
Ich habe 2 Requests (gleichzeitig), sprich, WaitForRequest(jeweils andere UID) wird 2x aufgerufen und damit auch das Application.ProcessMessages.

jetzt schreib ich einen Wert in das erste UID und ändere UID.RequestStatus = rsRequested und damit soll das WHILE abgebrochen werden. Pustekuchen. erst wenn ich den 2. Wert geschrieben habe und damit alle (wartenden) UIDs auf rsRequestet gesetzt habe gehts weiter.
Ich vermute, daß mit dem 2. Aufruf von WaitForRequest (und damit ProcessMessages) der erste auf Aussetzen ist und damit das WHILE nicht abgebrochen wird (siehe LOG unten)

Code:
  // WERTEANFORDERUNG klappt
  if WaitForRequest(ReqUID) then begin ....
Code:
// Wartet bis Wert da ist oder TimeOut - und hier steckt ein Fehler oder Seiteneffekt
function TCallbackValue.WaitForRequest(const UID:TCBUID):boolean;
const OneMilliSecond = 1 / (24 * 60 * 60 * 1000);
begin
  UID.RequestStatus := rsRequesting;
  // CODE fürs Wert anfordern spielt hier keine Rolle und funzt
  // Timeout setzen
  UID.TimeOutTime := Now + OneMilliSecond * RequestTimeout;
  // Warten
  while (Now<UID.TimeOutTime) and (UID.RequestStatus = rsRequesting) do begin
    LOG(UID.Index); // hier habe ich testhalber mal geloggt
    Application.ProcessMessages;
  end;
  result := UID.RequestStatus = rsRequested;
end;

das LOG der gesamte Geschichte (siehe ProcessMessages-Code):

/request #1 (UID#1)
1
1
1
/request #2 (UID#2)
2
2
2
2
/schreibe UID#1 (und RequestStatus = rsRequested) -> hier soll der erste Aufruf des ProcessMessages enden, MACHT ES ABER NICHT
2
2
...
2
2
/schreibe UID#2 (und RequestStatus = rsRequested)
2
1
/fertig, beide bekommen den wert, nur daß UID#1 erst auf UID#2 gewartet hat

es ist wichtig, daß immer die älteste Anforderung den Wert bekommt.

so, ich hoffe, ihr versteht, was ich meine, HEEELLPPPP !!!!!

[edit=sakura] Leerzeichen in Titel gesetzt. Mfg, sakura[/edit]
  Mit Zitat antworten Zitat
Proddi

Registriert seit: 4. Sep 2003
9 Beiträge
 
#2

Re: Überlappendes Application.ProcessMessages macht Unsinn

  Alt 26. Feb 2004, 12:54
Okay, ich beantworte mittlerweile mein Problem selbst

Das ganze führt zu einer Rekursion.

Also 1. ProcessMessages läuft: Eine MSG (bspw. Timer) löst in derselben Application ein 2. ProcessMessages aus. Dann bekommt, solange das 2. ProcessMessages läuft, das 1. ProcessMessages keine Rückmeldung, ist ja noch nicht zurückgekehrt.

Danke Proddi

Problem nur: Wie löst man sowas auf eine andere Art, sodaß das Programmhandling ungefähr gleich bleibt ?
  Mit Zitat antworten Zitat
Benutzerbild von Matze
Matze
(Co-Admin)

Registriert seit: 7. Jul 2003
Ort: Schwabenländle
14.929 Beiträge
 
Turbo Delphi für Win32
 
#3

Re: Überlappendes Application.ProcessMessages macht Unsinn

  Alt 26. Feb 2004, 13:03
Also, ich denke nicht, dass es am Application.ProcessMessages liegt, denn es gaht ja auch folgender Code einwandfrei:

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var i, j: integer;
begin
  for i := 1 to 5 do
  begin
    Application.ProcessMessages;
    for j := 1 to 10 do
      Application.ProcessMessages;
  end;
end;
Natürlich bringt der nix, aber da überschneidet's sich ja auch.
  Mit Zitat antworten Zitat
Benutzerbild von dizzy
dizzy

Registriert seit: 26. Nov 2003
Ort: Lünen
1.932 Beiträge
 
Delphi 7 Enterprise
 
#4

Re: Überlappendes Application. ProcessMessages macht Unsinn

  Alt 26. Feb 2004, 19:45
Naja, es ist schon in Verbindung mit Timern etwas... sagen wir mal "gewöhnungsbedürftig".
Weil:
Delphi-Quellcode:
procedure onTimer1(irgendwas:TObject);
begin
  doIrgendwasWasEtwasDauert;
  Application.ProcessMessages;
  |
  --> procedure onTimer2(wasAnderes:TObject);
      begin
        doNochWasWasLängerDauert;
        Application.ProcessMessages;
        |
        --> procedure onTimer1(irgendwas:TObject);
            begin
            .
            .
            . // usw. usf.....
            end;
      end;
end;
Also tatsächlich sowas wie eine Rekursion.
Wie man das lösen könnte weiss ich nicht, aber ich habe mein (sehr aktuelles) Problem gleicher Art so gelöst, dass ich in den TimerProcedures einfach kein Application.ProcessMessages benutzte. Fertig ist die Laube


gruss,
dizzy

\edit: Voraussetzung ist natürlich, dass die Bearbeitung innerhalb der Timer1Prozedur bis zum App.ProcessMessages mindestens so lange dauert, wie das Intervall von Timer2, und umgekehrt.
Oder die Timer würden asynchron gestartet, oder haben ungleiche Intervalle. Also in den meisten Fällen zumindest geht's in die Hose
Fabian K.
INSERT INTO HandVonFreundin SELECT * FROM Himmel
  Mit Zitat antworten Zitat
Proddi

Registriert seit: 4. Sep 2003
9 Beiträge
 
#5

Re: Überlappendes Application. ProcessMessages macht Unsinn

  Alt 26. Feb 2004, 20:01
@Matze
Dein Code läuft, kein Zweifel, aber ohne Rekursion. Dein ProcessMessages ruft nicht wirklich ein weiteres ProcessMessages auf. In deinem Beispiel wird das ProcessMessages immer der Reihe nach aufgerufen. Du hast nur 2 geschachtelte Schleifen, das ist aber keine Rekursion.
Das was ich meinte ist, wenn ein ProcessMessages#1 ein Event deiner Application aufruft, in dem du wiederum auch ProcessMessages#2 nutzt. Dann ist das Event aus ProcessMessages#1 noch nicht abgearbeitet und damit ProcessMessages#1 noch nicht fertig.

Ist im Nachhinein auch ein sehr blödes Thema, weiß auch nicht, wie ich es besser beschreiben soll. Naja, Lösung habe ich zwar noch nicht, aber Problem zumindest erkannt und damit 50% erreicht.

/edit: @dizzy - Richtig, mir passiert das mit SOCKET-Events, aber selbes Event-Handling wie dein Timer-Bsp. Leider fällt mir nichtmal auf dem Schei**haus eine vernünftige Alternative ein
  Mit Zitat antworten Zitat
Benutzerbild von dizzy
dizzy

Registriert seit: 26. Nov 2003
Ort: Lünen
1.932 Beiträge
 
Delphi 7 Enterprise
 
#6

Re: Überlappendes Application. ProcessMessages macht Unsinn

  Alt 26. Feb 2004, 21:04
Das einfachst wäre es wohl Threads zu verwenden. Mit entsprechend niedriger Priorität versehen klauen die dir auch nicht die Bedienbarkeit des Rechners (tpIdle z.B. ist immer wieder schön )
Man kann Multithreading in Schleifen sehr schön mit nem App.ProcessMessages faken, aber es ist unsauber, und wie du ja merkst nicht immer ganz unproblematisch.
Bei Threads immer auf Synchronized-Zugriffe auf VCL-Kompos achten, oder CriticalSections einrichten (hab ich nocht nicht gemacht, weiss also nicht wie. Aber zu diesem Thema findet sich sicherlich eine Menge!)


gruss,
dizzy


\edit: Und dass, ohne auf dem Porzellan-Orakel zu sitzen
Fabian K.
INSERT INTO HandVonFreundin SELECT * FROM Himmel
  Mit Zitat antworten Zitat
Proddi

Registriert seit: 4. Sep 2003
9 Beiträge
 
#7

Re: Überlappendes Application. ProcessMessages macht Unsinn

  Alt 27. Feb 2004, 20:06
Threads ist so eine Sache. Dazu müsste ich intern viele LOCK-Mechanismen einbauen, die ich mir bisher gespart habe. deswegen auch nur dieses synthetische Multitasking (wie heisst das richtig? ..präemtives MT??).

Ich denke mal der Knackpunkt ist meine Rangehensweise:
* Eine Funktion liefert in einer Zeit (0-timeout) ein ergebnis zurück (natürlich mehrfach gleichzeitig ausrufbar).

Ich sollte das ganze über Timer lösen (da kommt mir die Galle. zurück zum Pollen).
Die Funktion sollte neben dem Wert auch zurückgeben, ob sie überhaupt arbeiten konnte und dann quasi über eine Art CallBack(timer) den eigentlichen Wert/Fehler melden.

Ich zerstöre damit aber meinen sauberen und modularen Aufbau meines programmes (ist eine art spezieller TCP-Daten-Server (ca0...1000 clients -> dort scheitere ich auch mit multithreading. kann ja keine 1000 threads anlegen, da beschäftigt sich windows ja noch mehr mit sich selbst )

Gibt es da evtl noch eine andere 'Konzeption' ?
  Mit Zitat antworten Zitat
Antwort Antwort


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 08:18 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