Я хотел бы, чтобы в одном консольном приложении появлялись другие окна консоли и выводились на разные в разное время в консольном приложении С#. Предпочтительно в одном консольном приложении я запускаю некоторые другие консоли, пишу им и закрываю их во время окончательного блока исходного консольного приложения.
Какой идеальный способ сделать это на С#?
Я не думаю, что вы можете сделать это с помощью обычного консольного приложения. Ближе всего вы могли бы создать свою собственную форму в WinForms/WPF, которая примерно одинаково выглядела как обычное консольное окно.
Я предполагаю, что вы могли бы порождать дополнительные процессы, у каждого из которых была своя консоль, и писать им через сетевые подключения или именованные каналы и т.д.... было бы довольно уродливо, хотя.
Вы можете сделать это с помощью Auto/Manual EventWaitHandles в С# в сочетании с бесчисленными другими методами. Однако, вероятно, вам следует отступить и посмотреть, что вы пытаетесь выполнить, и посмотреть, будет ли приложение winform лучше соответствовать. Возможно, напишите более подробную информацию и попросите идеи.
В одном процессе может быть только один истинный стандарт, ошибка и выход.
Вы можете подделывать разные, особенно в .Net, потому что в конце концов они представлены как управляемые потоки, которые были бы хороши в push/pull и в трубе. Проблема состоит в том, что вывод/вход завершен, то есть бит, который может быть подключен к файлу, или когда вы запрашиваете ввод пользователя. Они просто не будут играть в мяч, поскольку ОС не предоставляет никакого метода мультиплексирования.
Используя простые средства, вы в лучшем случае можете сделать что-то, что отправило вывод в несколько разных окон, которые выглядели как консольное окно.
С большой сложностью вы также будете обрабатывать чтение. В сущности, вы пишете окно, которое претендует на роль консоли, и получить его достаточно близко ко всем небольшим тонкостям окон консоли (все чаще) сложно.
Было бы просто иметь (скажем) поддельную консоль на поток, создав такой класс. Я только беспокоюсь о том, что Out, In и Err легко следуют из этого.
public class MultiplexByThreadConsole : IDisposable
{
private readonly TextWriter originalOut;
private readonly TextWriter myOut = new IndividualMultiplex();
public MultiplexByThreadConsole()
{
this.originalOut = Console.Out;
Console.SetOut(this.myOut);
}
public void Dispose()
{
Console.SetOut(this.originalOut);
}
private class IndividualMultiplex : TextWriter
{
[ThreadStatic]
private readonly TextWriter actual;
// override all the required functions and any
// others you want to wrap
public override void Write(char c)
{
if (actual == null)
{
actual = MakeWhateverYouReallyWantToOutputTo();
}
actual.Write(c);
}
}
}
Затем где-то в главном (или где угодно):
using(new MultiplexByThreadConsole())
{
// off you go all threads during this get their own faked console.
}
Вероятно, вы включили In/Out/Err, указывая на некоторые обычные авторы/читатели объектов, которые сами были поддельной консолью.
Это, однако, довольно неприятно. Я бы сказал, что если вы действительно хотите запускать вещи, которые выглядят как отдельные консоли, тогда вы должны это сделать и запустить новый процесс для каждого из них с завершением работы с клеем, чтобы управлять ими (в чем-то похожим на концепцию передовых процессов Chrome за вкладку).