编写控制台应用程序时,与控制台窗口有关的EventHandler很少,但是我发现可以使用System.Console.CancelKeyPress
来中断正在进行的事件处理。
假设使用以下程序:
class Program
{
static void Main(string[] args)
{
Console.ForegroundColor = ConsoleColor.Blue;
Console.CancelKeyPress += myHandler;
while (true)
{
Console.WriteLine("Hello World!");
System.Threading.Thread.Sleep(1);
}
}
protected static void myHandler(object sender, ConsoleCancelEventArgs args)
{
args.Cancel = true;
Console.WriteLine(" Cancel property: {0}", args.Cancel);
Console.WriteLine("The read operation will resume...\n");
Console.ReadLine();
}
}
程序正在打印“ Hello World!”。无限地出现在屏幕上而且中断的工作原理是,我假设它们共享一个线程,并在您按下Ctrl + C的那一秒钟之内进入了Handler方法。当它在屏幕上打印出有关cancel属性当前状态的信息时,事件中的Console.ReadLine()被完全省略。
此预期的行为是为了避免阻止冲突,还是有一个技巧可以引发此事件时如何读取输入?如果您确实要退出,请像键入Y。
答案 0 :(得分:1)
您可以按照以下步骤做您想做的事情...
class Program
{
private static bool running = true;
private static bool stop = false;
static void Main(string[] args)
{
Console.ForegroundColor = ConsoleColor.Blue;
Console.CancelKeyPress += myHandler;
while (!stop)
{
if (running)
{
Console.WriteLine("Hello World!");
}
System.Threading.Thread.Sleep(1000);
}
Console.WriteLine("Exiting ...");
}
protected static void myHandler(object sender, ConsoleCancelEventArgs args)
{
args.Cancel = true;
running = false;
Console.WriteLine("Do you wish to resume... Y/N \n");
var resume = Console.ReadLine();
if (resume == "Y")
{
running = true;
}
else
{
stop = true;
}
}
}
我怀疑事件处理程序在与控制台窗口主线程不同的上下文中运行。以前我没有在控制台窗口中真正使用过事件,但是在WinForms中,GUI将在其自己的上下文线程上运行。
答案 1 :(得分:1)
cancel事件处理程序确实在另一个线程上运行(通过打印出线程ID进行验证)。
运行该事件的主线程和辅助线程不会“共享线程”,但是会使用控制台输出作为共享资源。
事件中的readline不会被忽略。尽管“主”线程确实确实继续编写“ Hello World”,但是如果您按Enter键,事件处理程序将有效地读取您输入的输入。
如果希望主线程“暂停”写入控制台,则必须找到一种机制来做到这一点。
这是一个非常幼稚的实现:
private static bool paused;
static void Main(string[] args)
{
Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
Console.ForegroundColor = ConsoleColor.Blue;
Console.CancelKeyPress += myHandler;
while (true)
{
if (!paused)
Console.WriteLine("Hello World!");
System.Threading.Thread.Sleep(1000);
}
}
protected static void myHandler(object sender, ConsoleCancelEventArgs args)
{
paused = true;
Console.WriteLine("Do you want to exit?");
Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
var answer = Console.ReadLine();
args.Cancel = answer != "y";
paused = false;
}