Frage

Ich bin mit einiger Drittanbieter-Bibliothek auf einen Server über Asynchron-Protokoll zu verbinden und Antwort zurück. Zum Beispiel Verfahren userid nach Usernamen wie folgt aussieht zu bekommen:

public int getUserid(String username) {
        int userid = 0;

    connection.call("getUserid", new Responder() {
        public void onResult(final int result) {
            System.out.println("userid: " + result);
            //how to assign received value to userid and return it?
        }
    }, username);

    //wait for response
    while (userid == 0) {
            try{
                Thread.sleep(100);
            } catch (Exception e) {}
        }


        return userid;
}

Das Problem ist, kann ich nicht „Ergebnis“ von der Server-Antwort zurückgegeben zuordnen, „userid“ Variable aus dem Verfahren (um es nach zurückzukehren). Wie dieses Problem zu lösen? Ich kann wahrscheinlich es bis zu einem gewissen Klassenvariable zuweisen, anstatt Verfahren variabel, aber ich mag es innerhalb Methode Rahmen halten, so muß ich nicht mit Concurrency Fragen.

Danke.

War es hilfreich?

Lösung

Wenn ich Ihre Frage richtig verstanden, Sie fragen, wie Sie eine Variable aus dem Inneren einer anonymen Klasse schreiben kann.

Anonyme Klassen können nur endgültige Variablen zugreifen, und kann nicht direkt „schreiben“ sie.

Eine einfache Lösung, die „gut genug“ ist, ist mit einem einzigen Wertfeld und ein Getter und Setter Art einer ValueBox Klasse zu erstellen. Sie können dann einen neuen in der Funktion als letzten Variable instanziiert und haben Ihre anonyme Klasse darauf zugreifen. Die anonyme Klasse wird seine Getter und Setter verwenden / Lese schreiben zu können.

Die Tatsache, dass die Variable endgültig ist, bedeutet nur, dass Sie nirgendwo anders die Referenz darauf abzielen können, aber Sie können immer noch den Inhalt des genannten Objekts von jeder Funktion ändern.

Das größere Problem, das Sie gehen zu müssen, ist in zu warten, bis der Rückruf aufgerufen wurde. Diese Art von wait-Schlaf könnte gut genug sein, aber Sie können Timeouts, Diskussionsthemen betrachten wollen, usw., je nachdem, was Sie erreichen wollen.

Darüber hinaus all dies setzt voraus, dass Sie nie auf die Verbindung zweimal anrufen werden. Andernfalls müssen Sie weitere Informationen zu uns auf Ihrem Synchronisationsmodell zur Verfügung zu stellen.

Hier ist ein Beispielcode:

public int getUserid(String username) {
        final ValueBox<Integer> userid = new ValueBox<Integer>();

        connection.call("getUserid", new Responder() {
                public void onResult(final int result) {
                        System.out.println("userid: " + result);
                        userId.setValue(result);
                        //how to assign received value to userid and return it?
                }
        }, username);

        //wait for response
        while (userid.isEmpty()) {
                try{
                        Thread.sleep(100);
                } catch (Exception e) {}
        }

      return userid.getValue();
}

Andere Tipps

Die einfachste Änderung ist so etwas wie java.util.concurrent.SynchronousQueue zu verwenden. Aber vielleicht wollen Sie ein Ereignis selbst angetrieben bereitzustellen Schnittstelle.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top