Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Cross-Platform-Entwicklung (https://www.delphipraxis.net/91-cross-platform-entwicklung/)
-   -   Verständnisproblem Android synchron/asynchron (https://www.delphipraxis.net/208387-verstaendnisproblem-android-synchron-asynchron.html)

Klapauzius 23. Jul 2021 07:34

Verständnisproblem Android synchron/asynchron
 
Irgendwie habe ich die Systematik von Firemonkey bezüglich synchroner und asynchroner Ausführung von Code in Android noch nicht durchschaut.

Beispiel 1 (Pseudocode)
Delphi-Quellcode:
settings:= tMySettings.create; //Erstellt eine Klasse, setzt Standartproperties oder wenn vorhanden liest inidatei ein und füllt die Properties
loadlanguage(settings.language); //unter android32 ist settings noch nicht initialisiert, in android 64 dagegen schon
oder Beispiel 2
Delphi-Quellcode:
if checkinput(edit1.text) then
   machwasmitmitdeminput; //funktioniert unter Android 64, funktioniert manchmal, manchmal nicht unter Android 32
Ja, ich kann die Probleme lösen
Delphi-Quellcode:
settings:= tMySettings.create;

TThread.ForceQueue(
    nil,
    procedure
    begin
        loadlanguage(settings.language);
end );

oder

ok:= checkinput(edit1.text);
TThread.ForceQueue(
    nil,
    procedure
    begin
        if ok them macheetwas mit dem Input;
end );
Frage: Unter welchen Umständen wird der Code synchron oder asynchron durchgeführt?

Ich selbst habe noch kein Muster gefunden und irgendwie ist es mir der Aufwand zu gross prohpylaktisch jeden Funktionsaufruf mit forcequeue zu kapseln.

himitsu 23. Jul 2021 08:41

AW: Verständnisproblem Android synchron/asynchron
 
Keine Ahnung was TMySettings.Create intern macht und daher kann niemand dazu was sagen.



Ja, viele Dialoge arbeiten in den mobilen Asyncrhron und man muß mit "Events" auf deren Antwort reagieren.
Zitat:

Delphi-Quellcode:
if checkinput(edit1.text) then
   machwasmitmitdeminput; //funktioniert unter Android 64, funktioniert manchmal, manchmal nicht unter Android 32
Delphi-Quellcode:
ok:= checkinput(edit1.text);
TThread.ForceQueue(
    nil,
    procedure
    begin
        if ok them macheetwas mit dem Input;
end );

Aber egal ob CheckInput synchron oder asynchron (Funktionsaufruf kehrt zurück, noch bevor der Nutzer was gemacht hat) ist,
das Beides macht das "gleiche", denn die Variable OK wird zur selben Zeit gesetzt, also kann es nicht unterschiedlich arbeiten.

Klapauzius 23. Jul 2021 09:54

AW: Verständnisproblem Android synchron/asynchron
 
Zitat:

Zitat von himitsu (Beitrag 1492698)

Ja, viele Dialoge arbeiten in den mobilen Asyncrhron und man muß mit "Events" auf deren Antwort reagieren.

Das ist mir bekannt, aber ich beziehe mich nicht auf Dialoge, sondern auf eigene Funktionen.

Beispiel TmySettings Pseudocode

Delphi-Quellcode:
TMySettings.create;
var
  pfad: String;
  ini: TMeminifile;
begin
  pfad := System.ioutils.TPath.Combine(System.ioutils.TPath.GetHomePath, 'Settings');
  pfad := System.ioutils.TPath.Combine(pfad, 'mysettings.ini');
  if fileexists(pfad) then
  begin
    ini: TMeminifile.create(pfad, TEncoding.utf8);
    try
      FLanguage:= ini.readString('App', 'Language','english');
      FLangVers:= ini.ReadFloat('App', 'LanguageV', 0);
      ......
    finally
      ini.free;
    end;
  end
  else
  begin
    ErstelleStandardwerte; //Fülle alle Properties mit Standardwerten
    ....
  end;

  end;

Zitat:

Aber egal ob CheckInput synchron oder asynchron (Funktionsaufruf kehrt zurück, noch bevor der Nutzer was gemacht hat) ist,
das Beides macht das "gleiche", denn die Variable OK wird zur selben Zeit gesetzt, also kann es nicht unterschiedlich arbeiten.
macht es aber bei mir definitiv unter Android 32:

Pseudo Beispiel
Delphi-Quellcode:
checkinput(Email:String):boolean;
begin
  result:= system.sysutils.sametext(settings.user.email, Email);
end;
[edited]

Das perfide für mich ist ja, dass "if checkkinput then ...." bei einfachen funktionen meist synchron funktioniert, bei komplexeren Funktionen aber unter android 32 oftmals nicht. Wann genau es aber nicht funktioniert ist mir eben nicht klar.
Völlig neben den Schuhen stehe ich, da die gleichen Funktionen unter Android 64 und Android 32 oftmals anders reagieren

himitsu 23. Jul 2021 17:37

AW: Verständnisproblem Android synchron/asynchron
 
Zitat:

Zitat von Klapauzius (Beitrag 1492700)
aber ich beziehe mich nicht auf Dialoge, sondern auf eigene Funktionen.

Ups, CheckInput ... hatte irgendwie einen Input-Dialog im Kopf :oops:


Hm, per se arbeiten all diese Funktionen ausschließlich synchron. (vielleicht abgesehn vom unbekannten ErstelleStandardwerte)

Zitat:

Delphi-Quellcode:
function checkinput(Email:String):boolean;
begin
  result:= system.sysutils.sametext(settings.user.email, Email);
end;

checkinput und sametext sind synchron, sie kehren imer ersz zurück, wenn fertig.
Es könnte natürlich sein, dass settings.user.email erst später geladen wird,
aber auch da arbeieten die synchron, nur eben noch mit dem "falschen" Wert.

Hier würde ich mal den Debugger fragen, was da wirklich verglichen wird.


Aber es könnte auch an der Codierung liegen (auch wenn es hier eigentlich zwischen 32 und 64 Bit keinen Unterschied geben sollte).
Versuch es mal mit AnsiSameText, anstatt SameText.

QuickAndDirty 25. Jul 2021 10:00

AW: Verständnisproblem Android synchron/asynchron
 
Viele Delphi Events laufen unter Android asynchron. Und viele Änderungen von TComponent Eigenschaften laufen zwar "synchron" aber in dem Sinne, das sie im selben thread passieren , jedoch häufig einfach nur messages auf der Message Queue ablegen. Also werden diese Änderungen erst wirksam wenn App idle ist.
Alles was mit Indy Komponenten zu tun hat erfordert es das du Threads verwaltest! Man Sendet und empängt Daten immer "asynchron" also in einem anderen Thread als dem Haupt-Thread.
Alle eigenen Funktionen und Folge-Funktionen die du aus Events heraus aufrufst könnten in einem anderen als dem Hauptthread laufen! Du musst das ab und an mal überprüfen wenn du ein Event verwendest von dem du nicht weist in welchem thread es läuft. Das ist von daher sowieso notwendig da du unter Android ja sowieso ständig Anonyme threads brauchst um deine App arbeiten zu lassen ohne das der Bildschirm (Hautpthread) einfriert und Android den Benutzer fragt ob er die App abschießen will, weil die ne Sekunde lang nicht auf Betriebsystem Messages reagiert hat.
Intern verwendet Firedac auch Threads wenn es mit Datenbank die über einen Datenbankserver erreichbar sind kommuniziert. Es kann passieren das es zu exceptions innerhalb dieser threads kommt, der code der diese Exceptions abfängt ist dann natürlich auch asynchron.
Eigentlich muss man sich irgendwie immer sorgen darum machen ob Code im Hauptthread oder in einem Nebenthread ausgeführt wird.
Ja ich war auch erstaunt wieviel man Wissen muss um das richtige zu tun....


Alle Zeitangaben in WEZ +1. Es ist jetzt 06:25 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