控制台选择停止应用程序
Console selection stops application
我是 运行 我服务器上的一个套接字服务器,我醒来时看到许多关于它无法访问的消息。原来在我睡觉之前,我在 window 中突出显示了一个 IP 地址,忘记按 Enter 键继续该过程。
这就是我现在在控制台中禁用 selection 的方式,但我仍然希望能够 select 应用程序不暂停。
#region Disable Quick-Edit Mode
[DllImport("kernel32.dll")]
static extern bool SetConsoleMode(IntPtr hConsoleHandle, int mode);
[DllImport("kernel32.dll")]
static extern bool GetConsoleMode(IntPtr hConsoleHandle, out int mode);
[DllImport("kernel32.dll")]
static extern IntPtr GetStdHandle(int handle);
const int STD_INPUT_HANDLE = -10;
const int ENABLE_EXTENDED_FLAGS = 0x80;
public static void DisableQuickEditMode()
{
int mode;
IntPtr handle = GetStdHandle(STD_INPUT_HANDLE);
GetConsoleMode(handle, out mode);
mode |= ENABLE_EXTENDED_FLAGS;
SetConsoleMode(handle, mode);
mode &= ~ENABLE_QUICK_EDIT;
SetConsoleMode(handle, mode);
}
我真的不想回到命令提示符的旧模式,因为拥有这些新功能确实有帮助(尤其是对开发人员而言),但我需要找到一种方法来防止应用程序当我暂停控制台时停止。
有趣的是,今天早上当我按下回车键时,所有尝试过的连接都被处理了,然后在处理完之后,它们就被丢弃了。这让我想知道,也许我写错了应用程序;我需要一个 "Console" 线程和一个 "Server" 线程。但我不确定这是否会有所作为。
在选择模式下,Windows 控制台中的任何线程在写入 stdout
或 stderr
时都会阻塞。哪个线程无关紧要。
您可以将控制台写入与服务器操作分开,并确保服务器线程永远不会写入控制台,但随后您会引入额外的线程管理和消息队列问题。
您可以像大多数人一样做:使用日志文件。如果您不想将文件写入应用程序,只需将 stdout
和 stderr
通过管道传输到一个文件,并使用一些 Windows 等同于 tail
来监视文件(或者像 Sublime 这样自动监控打开文件的文本编辑器)。
server.exe > server.log 2>&1
澄清一下:2>&1
表示stderr
(文件句柄2)应该是"merged into" stdout
(文件句柄1)。
对于简单的工具,在不同的线程中执行控制台写入可能确实是最简单的。
示例代码:
static BlockingCollection<string> messageQueue = new BlockingCollection<string>(new ConcurrentQueue<string>());
static Task messagePrinterTask;
private static void ConsoleWriteLine(string s)
{
messageQueue.Add(s);
}
private static void StartMessageQueuePrinter()
{
messagePrinterTask = Task.Run(() =>
{
try { while(true) Console.WriteLine(messageQueue.Take()); }
catch (InvalidOperationException) { } //CompleteAdding called.
});
}
private static void StopMessageQueuePrinter()
{
messageQueue.CompleteAdding();
messagePrinterTask.Wait();
}
我是 运行 我服务器上的一个套接字服务器,我醒来时看到许多关于它无法访问的消息。原来在我睡觉之前,我在 window 中突出显示了一个 IP 地址,忘记按 Enter 键继续该过程。
这就是我现在在控制台中禁用 selection 的方式,但我仍然希望能够 select 应用程序不暂停。
#region Disable Quick-Edit Mode
[DllImport("kernel32.dll")]
static extern bool SetConsoleMode(IntPtr hConsoleHandle, int mode);
[DllImport("kernel32.dll")]
static extern bool GetConsoleMode(IntPtr hConsoleHandle, out int mode);
[DllImport("kernel32.dll")]
static extern IntPtr GetStdHandle(int handle);
const int STD_INPUT_HANDLE = -10;
const int ENABLE_EXTENDED_FLAGS = 0x80;
public static void DisableQuickEditMode()
{
int mode;
IntPtr handle = GetStdHandle(STD_INPUT_HANDLE);
GetConsoleMode(handle, out mode);
mode |= ENABLE_EXTENDED_FLAGS;
SetConsoleMode(handle, mode);
mode &= ~ENABLE_QUICK_EDIT;
SetConsoleMode(handle, mode);
}
我真的不想回到命令提示符的旧模式,因为拥有这些新功能确实有帮助(尤其是对开发人员而言),但我需要找到一种方法来防止应用程序当我暂停控制台时停止。 有趣的是,今天早上当我按下回车键时,所有尝试过的连接都被处理了,然后在处理完之后,它们就被丢弃了。这让我想知道,也许我写错了应用程序;我需要一个 "Console" 线程和一个 "Server" 线程。但我不确定这是否会有所作为。
在选择模式下,Windows 控制台中的任何线程在写入 stdout
或 stderr
时都会阻塞。哪个线程无关紧要。
您可以将控制台写入与服务器操作分开,并确保服务器线程永远不会写入控制台,但随后您会引入额外的线程管理和消息队列问题。
您可以像大多数人一样做:使用日志文件。如果您不想将文件写入应用程序,只需将 stdout
和 stderr
通过管道传输到一个文件,并使用一些 Windows 等同于 tail
来监视文件(或者像 Sublime 这样自动监控打开文件的文本编辑器)。
server.exe > server.log 2>&1
澄清一下:2>&1
表示stderr
(文件句柄2)应该是"merged into" stdout
(文件句柄1)。
对于简单的工具,在不同的线程中执行控制台写入可能确实是最简单的。 示例代码:
static BlockingCollection<string> messageQueue = new BlockingCollection<string>(new ConcurrentQueue<string>());
static Task messagePrinterTask;
private static void ConsoleWriteLine(string s)
{
messageQueue.Add(s);
}
private static void StartMessageQueuePrinter()
{
messagePrinterTask = Task.Run(() =>
{
try { while(true) Console.WriteLine(messageQueue.Take()); }
catch (InvalidOperationException) { } //CompleteAdding called.
});
}
private static void StopMessageQueuePrinter()
{
messageQueue.CompleteAdding();
messagePrinterTask.Wait();
}