C# simultanen console input und output?
Schreibe ich eine server-app, und ich will es sein-Konsole basiert. Ich brauche den Benutzer zur Eingabe verschiedener Befehle, aber zur gleichen Zeit gibt es eine Möglichkeit, dass etwas wird die Ausgabe in der Konsole, während der Benutzer schreibt. Diese Verwirrungen der Puffer bis. Gibt es irgendeine saubere Möglichkeit, dies zu tun?
Dank.
- Ich bin mir nicht bewusst einen einfachen Weg, Nein. Ich habe gesehen, einige schrecklich Reife Produkte (gdb, windbg) nicht die Mühe mit diesem, obwohl Sie nicht in der Regel dump asynchron-info auf dem Bildschirm. Welche Art von Interaktion Sie suchen? Haben Sie herausgefunden, wie Sie denken, dass die Konsole sich Verhalten sollte?
- Es ist nicht ein Komplexes Konzept wirklich, alles was ich will ist, die der Benutzer zur Eingabe von text, sind in der Aufforderung die nach der letzten Zeile geschrieben. Wenn eine andere Zeile geschrieben wird, während der Benutzer Text eingibt, wird die Eingabeaufforderung neu gezeichnet, nachdem dieser Linie.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Begann ich Arbeit auf einem test-Programm, um zu zeigen, wie Sie konnten, teilen Sie die Konsole in ein Ausgabe-und ein Eingabe-Bereich, in dem die Eingabe-Bereich nach unten verschoben, wie der output-Bereich erweitert mit mehr Leistung. Es ist noch nicht perfekt, aber Sie möglicherweise in der Lage zu entwickeln, die es in der Antwort, die du suchst:
Persönlich würde ich verwenden, event-Handler hat es geschafft, eine Konsole, mit der sich sowohl ein-und outup zur gleichen Zeit, erstellen Sie eine Klasse ScreenManager oder was auch immer, in dieser Klasse fügen Sie eine leere RunProgram() mthod, erstellen Sie ein Ereignis mit dem Ereignishandler und die erforderlichen Variablen für das Lesen der Eingabe-Taste " - Konsole.ReadKey(bool).- Taste".
auf deinem main-Programm, creat eine Instanz der Klasse "whatev Sie nannten es", dann einen thread eröffnen der, die Instanzen interne Methode, Thread coreThread = new Thread(delegate() {myinstance.myProgramMrthod()});
Schleife in deiner Haupt, bis die Fäden laufen. while (!Thread.IsAlive) ;
dann erstellen Sie das main-Programm-loop.
dann für safty, verbinden Sie Ihre benutzerdefinierten thread, damit das Hauptprogramm nicht weiter, bis die custom thread geschlossen/entsorgt.
du hast jetzt zwei threads laufen separat.
zurück zu Ihrer Klasse, erstellen Sie einen Schalter in Ihrem event-handler-Methode.
stick allyour Logik resultiert, wie Sie damit umgehen wollen Schlüssel.
Wie man mehrere modifier Tasten in C#
vielleicht ein wenig helfen.
innerhalb Ihrer Instanz-Methode RunProgram() oder whatev Sie es nennen wollen, nachdem Sie das getan haben, was auch immer code, den Sie benötigen, erstellen Sie eine Endlosschleife zu überprüfen, key ändern.
diese Schleife speichert eine beliebige Taste gedrückt und dann überprüft, um zu sehen, wenn es einen neuen Schlüssel, wenn true, wird das Ereignis ausgelöst.
haben Sie nun den Kern von, was Sie suchen, eine Zeichenfolge, die Schleifen askng für einen neuen Schlüssel, während die main-loop ist frei, zu zeigen, was text, den Sie anzeigen möchten.
zwei behebbaren Fehler mit dabei, die ich mir vorstellen kann, ist "Standard" inneren Schalter " drucken auf der Konsole Kappen oder strings. und der andere ist ein beliebiger text Hinzugefügt, um die Konsole Hinzugefügt wird an der cursor-Punkt, so fügt es dem text, den der Benutzer gerade Eingaben.
hwoever ich, da habe ich es gerade so geschafft, wie man manager wird der text wurde Hinzugefügt, um die Konsole. wieder im event. ich konnte die Methoden und Funktionen im gesamten, aber die Ereignisse hinzufügen, verschieben Forensoftware auf dem Programm, denke ich.
okay also wir wollen in der Lage sein, das hinzufügen von text auf der Konsole, ohne dass Sie stören den Anregungen, die wir geben. halten Sie die Eingabe an der Unterseite;
erstellen Sie einen neuen Delegaten, hat eine Signatur mit einem string-argument, delegate void myDelegate(string Arg). dann erstellen Sie eine Veranstaltung mit diesem delegieren, nennen Sie es, newline, newinput, whatev, die Sie mögen.
den ereignisbehandler wird eine string-argument (repersenting das update für die Konsole text: was möchten Sie zum einfügen in die Konsole über die Anwender-Eingabe) wird er schnappen Sie sich den text, den der Anwender über die Eingabe in der Konsole, speichern, dann drucken Sie die paramiter string auf der Konsole aus, dann drucken Sie die Benutzer-Eingabe underneith.
persönlich, die ich wählte, zu erstellen Sie eine statische Zeichenfolge an der Spitze außerhalb der Methode initialisieren Sie Sie leer, denn die wird Häufig verwendet, und Sie wollen nicht die Schaffung einer neuen identifyer und dann die Initialisierung der variable jedesmal, wenn die Methode aufgerufen wird, dann entsorgen Sie es am Ende der Methode, nur, wieder eine neue, wieder und wieder.
Aufruf der string "input" oder was auch immer.
in den Standard-Bereich der keychange Ereignis-handle hinzufügen Eingabe +=newkey.
in der Consolekey.geben Sie im Abschnitt console writline Eingang dann input = string.leer Oder string = "".
in der event-handler fügen Sie einige Logik.
Wenn Sie müssen, um die Ausgabe zu kommen, während der Benutzer die Eingabe, die ich empfehlen, das senden der Ausgabe in einem neuen Fenster. So könnten Sie haben ein Fenster, das verwendet wird, um die Anwendung zu starten und dann erstellt einen thread öffnen Sie eine neue Konsole für die Eingabe und dann geht es weiter zu versenden Meldungen an die ursprünglichen Fenster. Ich denke, Sie laufen in zu viele resource-locking Problemen, wenn Sie versuchen, alles im gleichen Fenster.
Diese Art der Sache wird ein etwas einfacheres problem zu behandeln, wenn Sie den server als ein client/server-Anwendung. Lassen Sie den server "n" - verbindungen zu client-admin Anwendungen, das senden von Befehlen und empfangen Ausgang. Die client-Anwendung könnte völlig separaten Eingang und Ausgang, mit einem thread zu behandeln Eingang, und zu handhaben Ausgabe.
Den Ausgang Gewinde blockieren könnte, wenn die Eingangs-thread ist in der Mitte in einer Linie, und entsperren, wenn Sie die Zeile entweder gelöscht werden oder begangen haben.
Habe ich meine beispielsweise das arbeiten mit
Console.MoveBufferArea()
, aber beachten Sie, dass das nicht funktionieren auf anderen Plattformen als Windows, weil die Methode nicht implementiert auf diesen Plattformen.Mit diesem Beispiel würden Sie
Read()
stattConsole.ReadLine()
undLog(...)
stattConsole.WriteLine(...)
im code.Haben Sie versucht, Sie anzurufen,OpenStandardInput, Lesen alle Eingabe-und zurücksetzen der position, dann schreiben auf den Ausgabe-stream. Danach können Sie nennen OpenStandardInput wieder und füllen Sie die Daten wieder in den stream.
Es gibt keine perfekte Weg, dies zu erreichen, denke ich. Was telnet funktioniert (zumindest die Letzte version, die ich verwendet habe) war nicht drucken einer beliebigen Eingang (nur Lesen der Tastatureingaben) und drucken Sie einfach die Ausgabe, wie es ankommt. Die alternative ist die Speicherung aller Daten, die benötigt werden, um die Ausgabe auf der console in einen Puffer, und nur dann gedruckt, sobald der Benutzer die Eingabe beendet Ihren Befehl. (Man könnte auch Zeitstempel die Ausgabe, um es noch deutlicher.) Ich kann wirklich nicht sehen, keine bessere alternative hier - Sie sind unvermeidlich, um Probleme mit der Verwendung einer synchronen I/O-Schnittstelle (d.h. die Kommandozeile) zusammen mit asynchronen Operationen im backend.