C# 如何通过按键中断程序
我想按T键来中断我的制作人-消费者程序。我搜索了很多答案,但我不明白为什么它不起作用C# 如何通过按键中断程序,c#,multithreading,monitor,C#,Multithreading,Monitor,我想按T键来中断我的制作人-消费者程序。我搜索了很多答案,但我不明白为什么它不起作用 static void Main(字符串[]args) { 缓冲区=新缓冲区(); Produtor prod=新Produtor(缓冲区); Thread threadProdutor=产品CriarThreadProdutor(); Consumidor cons=新Consumidor(缓冲区,100000); Thread threadConsumidor=cons.CriarThreadConsumi
static void Main(字符串[]args)
{
缓冲区=新缓冲区();
Produtor prod=新Produtor(缓冲区);
Thread threadProdutor=产品CriarThreadProdutor();
Consumidor cons=新Consumidor(缓冲区,100000);
Thread threadConsumidor=cons.CriarThreadConsumidor();
threadProdutor.Start();
threadConsumidor.Start();
threadProdutor.Join();
threadConsumidor.Join();
while(Console.KeyAvailable&&Console.ReadKey(true.Key==ConsoleKey.T)
{
环境。退出(0);
}
}
我在while中添加了一个断点,但程序甚至无法到达那里。将循环放在您的
Join()
调用之后,当您检查控制台的输入时,线程将已经完成,因此您需要颠倒顺序
此外,只有在有可用钥匙且钥匙为T
时,才会进入while
循环并继续运行。您想要的是相反的:循环直到一个键可用并且它是T
最后,Console.ReadKey()
阻塞直到按下一个键,因此您也不需要检查Console.KeyAvailable
,除非您在等待t
时想做其他事情(例如显示进度或检查线程是否自行完成)
while(Console.ReadKey(true.Key!=ConsoleKey.T)
{
//什么也不做。。。
}
//T已按下
//向线程发出停止的信号
//设置标志、Cancel()和CancellationTokenSource等。
//等待线程终止
threadProdutor.Join();
threadConsumidor.Join();
//退出程序
环境。退出(0);
要在等待中断键时显示进度,可以像这样重写循环
TimeSpan progressInterval=TimeSpan.FromSeconds(1);
//complete是消费者设置的简单标志
//仅在KeyAvailable时调用ReadKey(),这样它的阻止时间就不会超过updateInterval
而(!complete&&(!Console.KeyAvailable | | Console.ReadKey(true.Key!=ConsoleKey.T))
{
WriteLine($“当前时间为{DateTime.Now:HH:mm:ss.fff}”);
线程。睡眠(进程间隔);
}
请注意,这样做的缺点是在整个progressInterval
期间始终处于睡眠状态,即使在此之前已满足退出条件。一个简单的解决方法是将两次检查之间的时间缩短到1/n
,然后仅在每次n
第次检查后显示进度
TimeSpan progressInterval=TimeSpan.FromSeconds(1);
常量int ReadsPerProgressInterval=10;
TimeSpan sleepTimeout=新的TimeSpan(progressInterval.Ticks/ReadsPerProgressInterval);
int readCount=0;
//complete是消费者设置的简单标志
//仅在KeyAvailable时调用ReadKey(),这样它的阻止时间就不会超过updateInterval
而(!complete&&(!Console.KeyAvailable | | Console.ReadKey(true.Key!=ConsoleKey.T))
{
//直到progressInterval结束后,才会显示进度
//要显示初始进度,请执行以下操作:
//A)更改为==1,或。。。
//B)将进度显示复制到循环之前
如果(++readCount%ReadsPerProgressInterval==0)
WriteLine($“当前时间为{DateTime.Now:HH:mm:ss.fff}”);
睡眠(睡眠超时);
}
我确实在使用Console.WriteLine()添加显示进度,那么,我需要使用KeyAvailable吗?是的,在这种情况下,您需要检查KeyAvailable
以确保ReadKey()
不会阻塞太长时间。我已经更新了我的答案,以说明如何做到这一点。