C# 取消按键-接受输入
在编写控制台应用程序时,没有太多与控制台窗口相关的事件处理程序,但我发现可以使用C# 取消按键-接受输入,c#,events,.net-core,C#,Events,.net Core,在编写控制台应用程序时,没有太多与控制台窗口相关的事件处理程序,但我发现可以使用System.Console.CancelKeyPress中断正在进行的事件进程 假设以下程序: class Program { static void Main(string[] args) { Console.ForegroundColor = ConsoleColor.Blue; Console.CancelKeyPress += myHandler;
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的瞬间,它进入处理程序方法。当它在屏幕上打印出有关cancel属性当前状态的信息时,事件中的Console.ReadLine()被完全忽略
这种行为是为了避免阻塞冲突,还是在触发此事件时存在读取输入的技巧?如果您真的想退出,请输入Y。您可以按如下方式执行您希望执行的操作
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将在其自己的上下文线程上运行。您可以按如下所示执行您希望执行的操作
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将在其自己的上下文线程上运行。取消事件处理程序确实在另一个线程上运行(通过打印线程id来验证这一点) 运行事件的主线程和次线程不“共享线程”,但会将控制台输出用作共享资源 事件中的读取行不会被忽略。尽管“main”线程确实继续编写“helloworld”,但如果按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;
}
cancel事件处理程序确实在另一个线程上运行(通过打印线程id来验证这一点) 运行事件的主线程和次线程不“共享线程”,但会将控制台输出用作共享资源 事件中的读取行不会被忽略。尽管“main”线程确实继续编写“helloworld”,但如果按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;
}
谢谢你的解释,这确实澄清了它为什么是这样。谢谢你的解释,这确实澄清了它为什么是这样。