MSDN.WhiteKnight - Stack Overflow answers
Ответ на "Ошибки при работе с консолью в отдельном потоке"
Answer 801047
Пользоваться консолью в не-консольных приложениях, как ни странно, можно (ну, оставляя в стороне практическую целесообразность такой "методики"). Из какого потока обращаться к консоли совершенно неважно - все операции на консоли потокобезопасны, так как синхронизируются блокировками на глобальном объекте. Приведенный в вопросе код почти рабочий, он не учитывает только одну деталь: после уничтожения и пересоздания консоли прямым вызовом API-функций внутри класса Console остаются объекты TextReader/TextWriter с протухшими файловыми дескрипторами, которые необходимо пересоздать.
Нужно заменить вызов AllocConsole на вызов приведенного ниже метода CreateConsole:
[DllImport("kernel32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] private static extern bool AllocConsole(); [DllImport("kernel32.dll", SetLastError = true)] internal static extern uint GetConsoleCP(); public static bool CreateConsole() { bool res = AllocConsole(); if (res == false) return false; uint cp = GetConsoleCP(); //Пересоздаем stdout StreamWriter wr = new StreamWriter( System.Console.OpenStandardOutput(),Encoding.GetEncoding((int)cp)); wr.AutoFlush = true; System.Console.SetOut(wr); //Пересоздаем stdin TextReader read = new StreamReader( System.Console.OpenStandardInput(), Encoding.GetEncoding((int)cp)); System.Console.SetIn(read); return true; }
И поправить клавиатурный цикл (выкинуть ужасный код со Thread.Abort и сделать хотя бы что-то похожее на нормальную синхронизацию):
private static volatile bool StartConsole = false; public static void Console() { if (CreateConsole()) { /*Работа с консолью...*/ FreeConsole(); } StartConsole = false; } public static void SetConsole() { while (true) if (/*условие входа*/ && !StartConsole) { StartConsole = true; Thread ConsoleThread = new Thread(Console); ConsoleThread.Start(); } }
Тогда все заработает.
Основано на коде из данной темы: Console error after FreeConsole is called
Content is retrieved from StackExchange API.
Auto-generated by ruso-archive tools.