Im StackTrace "zurückgehen"

Kai008

Erfahrenes Mitglied
Ich würde ein Programm gerne per Telnet steuerbar machen. Zuerst kommt der Login, dann ein Menü, je nach dem Punkt ein weiteres Untermenü (oder disconnect) usw.
Jedes dieser Dinge würde ich gerne in eine eigene Methode setzen. Jetzt habe ich aber Angst, das wenn man es oft benutzt und/oder mehrere Tage lang verbunden bleibt ihm irgendwann der Stack ausgeht. (Stack Overflow).
Deshalb habe ich mich gefragt, ob es möglich ist, wenn man wieder in einer Methode landet in der man schon war (wie z. B. das Startmenü) man alle Stackeinträge dazwischen entfernen kann.

Eine andere Möglichkeit, die mir gerade jetzt beim schreiben eingefallen ist, wäre es jeden neuen Methodenaufruf in einen neuen Thread zu machen. Aber würdet ihr das für klug halten?
 
Hallo,

also von Threads würde ich abraten, da das ne Menge Overhead ist, und das zusammenführen dann am Ende sehr schwer ist.
Ich würde eher zu einem Vector raten, der den "Weg" des Benutzers speichert. Sobald er zurückgeht, wird das letzte Element gelöscht. Dies entspricht auch deiner ersten Idee ;)

Gruß
BK
 
Danke, wobei ich denke, das sich dafür ein Stack besser eignet.
Aber es löst nicht mein eigendliches Problem. Hier ein Hardcodet-VHIDT-Pseudocode zum verstehen:

Java:
String LINE_WRAPPLER = System.getProperty("line.separator");

public static void login()
{
	String username;
	String password;

	do
	{
		write("Username:" + LINE_WRAPPLER")
		username = read();
		write(LINE_WRAPPLER + "Password:" + LINE_WRAPPLER")
		password = read();
	}
	while(!loginCorrect(username, password));
	menu();
}
public static void menu()
{
	write("0) Do Something"+ LINE_WRAPPLER);
	write("1) Do Something other" + LINE_WRAPPLER);
	write("2) Go Back" + LINE_WRAPPLER);

	byte input = -1;
	do
	{
		byte dummyInput;
		try
		{
			dummyInput = Integer.parseInt(read());

			if(dummyInput => 0 && dummyInput <= 2)
				input = dummyInput;
		}
		catch(NumberFormatException e) {}
	}
	while(input == -1);

	if(input == 0)
	{

	}
	else if(input == 1)
	{

	}
	else if(input == 2)
	{
		login();
	}
}

Also rufen sie die Methoden gegenseitig auf. Damit werden die Aufrufe irgendwann so gestapelt sein, das der Stacktrace keinen Platz mehr hat. Threads würden dafür sorgen, das zumindest die Methode (wie hier am Anfang "login()") nicht beim Aufruf von "menu()" wartet und dadurch im Trace vermerkt wird, sonst fertig abgearbeitet wird.
 
Hallo,

ich verstehe gerade dein Problem nicht. Warum sollte dem Nutzer der Stack ausgehen, nur weil er mehrere Tage verbunden war?

Auf dem Stack landet ja zum großteil nur die Methoden die gerade ausgeführt werden. Sobald diese beendet werden, verschwindet das alles wieder vom Stack.

Aber zum Speichern der ausgeführten Actions schau die mal das Command-Pattern an.
http://de.wikipedia.org/wiki/Kommando_(Entwurfsmuster)

Gruß

Sascha
 
Ja, das war falsch ausgedrückt. Natürlich nicht durch die Verbindung, sondern der Benutzung. (Sobald man nichtmehr verbunden ist soll read() eine IOException bis ganz nach oben throwen, dadurch ist der Stack wieder größtenteils leer.)
Wenn er sich in meinen Beispiel Authentifiziert, das Menü angezeigt wird und er wieder zurückgeht landet trotzdem immer mehr darauf, weil die Methoden ja verschachtelt sind. Damit sammelt sich mit jeder Aktion mehr an, bis der User disconnected und er per throw zurückgeht. (Oder ihm eben der Platz ausgeht.)
 
Also wird bei dir nie eine Methode beendet, bis man disconnected ist? Das wäre aber ein schlechtes Konzept. Das würde heißen, wenn man viel arbeitet, würde der Stack voll laufen.
Das kann ich mir gar nicht vorstellen, dass du das so implementiert hast.
Wenn der User eine Aktion ausführt, muss die Methode doch beendet werden.

Gruß

Sascha
 
Hi,

anstatt deines Aufrufes der menu()-Methode in Zeile 16 könntest du auch ein einfaches return schreiben.
Dann musst du aber in der main() noch eine Schleife machen, so dass die Abfrage erneut angezeigt wird.

Gruß
BK
 
Ja, aber da jede Aktion ja eine eigene Methode hat, muss die Aktion die Folgeaktion aufrufen, wodurch die ursprüngliche Aktion an der Aufrufstelle "stehenbleibt", wärend die darunter aufgerufene (usw..) abgearbeitet wird.

Würde ich in Zeile 16 ein return machen (ich gehe jetzt davon aus, das du angenommen hast, das das Menü vor dem Login angezeigt wird), würde er in Zeile 50 weiter abarbeiten (vom Code her, wies genau gemacht wird weiß ich nicht.), ich würde aber das Menü ohne erneuten Aufruf der Methode nichtmehr angezeigt bekommen.
 
Deshalb hab ich ja auch noch geschrieben, dass du eine Schleife brauchst ;)

// Edit: eine andere Möglichkeit wäre eventuell das Werfen von Exceptions. Angenommen, du wirfst eine BackToMenuException (musst halt schnell selber machen), dann wird die innerhalb der menu() abgefangen und sorgt dafür, dass die Methode erneut durchläuft. Du musst halt die Exceptions von Throwable erben lassen, sonst musst du bei jeder Methode einen ewig langen "throws"-Teil mit allen möglichen Exceptions anhängen ;)

Gruß
BK
 
Zuletzt bearbeitet:
Exceptions müssen doch sowieso von Throwable erben, oder? (Zumindest indirekt.)
Aber wenn sich hinter den Menüpunkt "Do Something" im Beispiel z. B. ein anderes Menü verbergen würde, und dieses wieder eines aufrufen würde, könnte man mit "return" ja nichtmehr einen Schritt nach hinten gehen, sondern würde immer zurück zum Anfang kommen. Die Schleife würde zwar neu starten, aber das wäre doch schon sehr nerfend.
Und würden eine solche Menge trys nicht den Code mehr oder weniger unleserlich machen?
 

Neue Beiträge

Zurück