Mehrere REST-Anforderungen parallel zu FireMonkey

8

Ich baue in Rad Studio XE7 eine Firemonkey-App, bei der ich mit einem einzigen Klick mehrere (etwa 7) Web-Service-Aufrufe mit TRestRequest machen muss. Jeder Webservice gibt ein json-Objekt zurück, das dann das Dataset auffüllt. Ich suche nach einem Weg, um diese Anrufe gleichzeitig und nicht über die Benutzeroberfläche der App zu sperren.

Welchen Weg empfehlen Sie, dies zu tun? Ich habe gesehen, dass Embarcadero neue Aufgaben- und Funktionsfunktionen für das Threading eingeführt hat, aber ich bin mir immer noch nicht sicher, ob wir das und wie verwenden können. Außerdem habe ich gesehen, dass es eine Funktion gibt, um TRestRequest asynchron mit dieser Funktion auszuführen:

%Vor%

Ich kann jedoch keine Dokumentation darüber finden, wie man diese Methode verwendet und was sie tut.

Jede Eingabe wird sehr geschätzt.

    
Emulic 03.12.2014, 18:46
quelle

1 Antwort

2

Die Methode ExecuteAsync(ACompletionHandler: TCompletionHandler = nil; ASynchronized: boolean = true; AFreeThread: boolean = true) ist in der Tat der richtige Weg. Wie der Name schon sagt, ist es asynchron; Das bedeutet, dass Ihr Programm nach dem Absetzen der Anforderung oder sogar nach dem Absetzen mehrerer Anfragen weiterhin reagiert.
Es ist jedoch wichtig, dass Sie diese unterschiedlichen Anforderungen von verschiedenen Objektinstanzen auslösen. Wenn Sie eine ExecuteAsync von einer TRESTRequest -Instanz auslösen, die bereits eine ExecuteAsync ausführt, wird die neue Anforderung die bestehende Anfrage in die Quere kommen. Sie müssen für jeden parallelen Aufruf eine separate Instanz TRESTRequest erstellen.

Beachten Sie, dass der erste Parameter eine Prozedur ist; Sie übergeben ein Verfahren Ihrer Wahl als diesen Parameter. Die einzige Voraussetzung ist, dass das Verfahren die richtige Unterschrift hat; In diesem Fall ist es eine Prozedur, die keine Parameter hat.

Die ExecuteAsync-Methode ist in REST.Client definiert. (Ich habe Delphi XE-10.1. Berlin, so hat es einen zusätzlichen Parameter, ACompletionHandlerWithError - der bei einem Fehler aufgerufen wird. Das Prinzip bleibt jedoch gleich).

Werfen wir einen Blick darauf:

%Vor%

In diesem Fall wird ein neuer Thread erstellt, in dem der REST-Request ausgeführt wird. Wenn die Antwort eintrifft, wird sie von ACompletionHandler behandelt.
Standardmäßig läuft ACompletionHandler auf dem neuen Thread, der von ExecuteAsync erstellt wurde. Wenn Sie möchten, dass es im Hauptthread ausgeführt wird, sollten Sie ASynchronized auf true setzen.

Aber wie erhalten Sie Zugriff auf diese Antwort und machen sie für den Rest Ihres Programms zugänglich?

Die TRESTRequest-Klasse von FireMonkey hat eine Eigenschaft Response , die sich auf das TRESTResponse-Objekt bezieht, das die Antwort des Servers auf unsere Anfrage enthält.
Leider werden weder das TRESTRequest- noch das TRESTResponse-Objekt an unseren CompletionHandler übergeben!

Also müssen wir dem CompletionHandler irgendwie diese Informationen geben. Glücklicherweise können wir eine Methode als CompletionHandler verwenden.

Nehmen wir an, dass die Klasse, die die resultierenden Daten verarbeiten wird, DataOwner heißt. Unser Ziel ist, dass DataOwner Zugriff auf die TRESTResponse-Instanz hat, die unserer TRESTRequest-Instanz zugeordnet ist.
Der einfachste Weg dazu ist TRESTRequest und / oder TRESTResponse ein Mitglied von DataOwner zu werden.

Nehmen wir an, Ihre Anforderung wurde von einer TRESTRequest-Instanz mit dem Namen MyRESTRequest ausgelöst und von einer Funktion processResponse verarbeitet. Sie würden den folgenden Code verwenden:

%Vor%

Wenn Sie mehrere Anfragen parallel absetzen wollen, müssen Sie dieses Muster mehrmals verwenden. Leider haben wir in unseren Completion Handlern keinen direkten Zugriff auf die TRESTRequest-Instanz oder die TRESTResponse-Instanz, da wir die Buchhaltung selbst durchführen müssen. Mit anderen Worten, es liegt am Programmierer, sicherzustellen, dass der Vervollständigungshandler das richtige Response-Objekt verarbeitet.

    
S.L. Barth 28.11.2016 14:50
quelle