![]() |
Welches Form des wechselseitigen Auschlusses(Semaphore)?!
Hallo,
ich habe eine Methode meines Objekts, die intern Application.ProcessMessages aufruft, ich will aber nicht, dass in die Methode nocheinmal "reingesprungen" wird, solange sie noch aktiv ist. Meine Frage ist nun, welche Synchronisationsmethoden (viell. eine Semaphore?) ist da sinnvoll? Oder kann man hier eine TCriticalsection nutzen? so sieht meine Methode grob aus:
Delphi-Quellcode:
Danke schonmal für eure Anregungen
begin
//--------> Hier SyncEintritt MachEtwasHier; MachEtwasDort; while (...) do begin MachHierWasSpektakulaeres; Application.ProcessMessages; end; //--------> Hier SyncAustritt end; P.S.: Habe das Script von Luckie habe ich gelesen |
Re: Welches Form des wechselseitigen Auschlusses(Semaphore)?
CriticalSection geht nicht, da du in eine CritcalSection mehrmals hineinlaufen kannst, solange du im gleichen Thread bist. Und das ist hier ja der Fall. Semaphore oder Event würde gehen, aber:
Application.ProcessMessages zu verwenden ist (fast) immer ein falscher Konzeptansatz. Und wenn du schon über Synchronistaionsobjekte sprichst, warum nimmst du nicht gleich einen Thread. Meistens läßt sich ja mit einem Thread das schlechte ineinanderwurschteln von Application.ProcessMessages vermeiden. Lies dir mal zu Application.ProcessMessages das hier durch: ![]() du bist dir ja der Problematik schon bewusst. Versuch sie besser gleich komplett zu umgehen. |
Re: Welches Form des wechselseitigen Auschlusses(Semaphore)?
eine Semaphore würde auch nur gehen wenn diese nicht blockiert. Da hier kein Zugriff durch mehrere Threads stattfindet sondern es immer wieder der gleiche Thread ist kann man es einfach über eine Variable absichern.
|
Re: Welches Form des wechselseitigen Auschlusses(Semaphore)?
@sirius:
Zitat:
den Symptomen rum, müsste mir aber die Auslöser dafür vornehmen. Das Problem was ich habe ist folgendes: Ich habe eine Kommunikation zwischen einem Gerät und meiner PC-Soft. Es ist eine Frage Antwort Spielchen: Frage: Gib mir Daten auf Adress 0x1000 ...
Delphi-Quellcode:
...
// Hier liegt mein Problem, da ich aktiv auf die Antwort warte (warten muss);
// Ich warte auf 6 Bytes (wenn diese in einer Zeitpanne nicht da sind frage ich nochmals nach (3-mal) // dann muss ich auf einen Timeout detektieren Antwort: Hier die Daten Und das ist alles in einem Funktionsaufruf gekapselt... |
Re: Welches Form des wechselseitigen Auschlusses(Semaphore)?
Das läuft in einem Thread ab... Der Thread heißt 'TAcquireDataThread'. Ihm übergibst du den Port (die 'Adresse') und der macht das dann für dich, also antriggern, warten, Daten lesen (max 3x) etc... Über das OnTerminate-Event teilt er dir mit, das er fertig ist (fehlerfrei oder auch nicht). Das blockiert deine Anwendung nicht und Du kannst problemlos mehrere davon abfeuern. Wenn immer nur ein Leser an einem bestimmten Port lauschen darf, dann erzeugst/öffnest du beim Thread-Beginn eine Semaphore mit Namen 'Port<Portnummer>'. So ist sichergestellt, das immer nur ein Thread pro Port aktiv ist...
Alternativ kannst du den Thread auch fehlerbedingt terminieren lassen, wenn es die Sempahore schon gibt. |
Re: Welches Form des wechselseitigen Auschlusses(Semaphore)?
Bisher habe ich meine Funktionen immer so gehabt:
function HoleStatus(Status:TStatus) : Integer; Diese habe ich dann aufgerufen und den Status in der GUI angezeigt, als direkten Rückgabwert habe ich dann ausgewertet, ob die Funktion erfolgreich ausgeführt wurde. Angenommen ich mache das jetzt über einen Thread, dann weiss ich ja nie genau, wann er fertig ist, oder? Denn wenn ich Schreizugriffe auf mein Gerät habe, dann muss ich nach Aufruf defintiv wissen, dass der Schreibzugriff, erfolgreich war. @alzaimar: Den 'TAcquireDataThread' muss ich mir selbst erstellen, richtig?! Oder gibt es soetwas ähnliches schon? Gruß und Danke! |
Re: Welches Form des wechselseitigen Auschlusses(Semaphore)?
@alzaimar:
Kannst du mir da evtl. mit ein bisschen Quellcode / Pseudocode auf die Sprünge helfen, da ich dort nicht so richtig weiterkomme. Wenn du mir mit dem Ansatz hilfst, wäre echt super! Danke |
Re: Welches Form des wechselseitigen Auschlusses(Semaphore)?
Ich denke, dass du nur deine Benutzeroberfläche verriegeln musst!!
(Tip: Actions verwenden) Damit wird verhindert, dass eine Message in Application.ProcessMessages verarbeitet wird und du erneut in deiner Prozedur landest.
Delphi-Quellcode:
Nachtrag:
begin
BtnStart.Enabled := False; // <=== try MachEtwasHier; MachEtwasDort; while (...) do begin MachHierWasSpektakulaeres; Application.ProcessMessages; end; finally BtnStart.Enabled := True; // <=== end; end; wenn das oben eine Methode deiner eigenen Klasse ist, dann wäre Folgendes empfehlenswert:
Delphi-Quellcode:
Mit dieser Änderung kannst du von Aussen vorgeben, was passieren soll, während die Methode arbeitet.
begin
// BtnStart.Enabled := False; // wird ins Formular verlagert MachEtwasHier; MachEtwasDort; while (...) do begin MachHierWasSpektakulaeres; // Eventhandler aufrufen, falls vorhanden if Assigned(FOnProgress) then FOnProgress(self); // <=== end; // BtnStart.Enabled := True; // wird ins Formular verlagert end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 20:07 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz