为何C#中While(true)无限线程循环会意外终止?
嘿,来聊聊你的线程为啥跑着跑着就停了~
首先,你的问题核心原因其实很简单:你用了rand.Next()但根本没创建Random对象的实例! 代码里从头到尾没写Random rand = new Random();,这会导致程序抛出NullReferenceException空引用异常,直接把你的随机输出线程搞崩终止了——这就是为啥跑三行半就停的原因。
另外还有个小坑:你用SendKeys.SendWait来输出字符,这个方法是把按键发送给当前有焦点的窗口。虽然一开始控制台窗口是焦点能输出,但如果中途不小心点了别的窗口,SendKeys就不会往控制台输出了,但这不是线程终止的主要锅,主要还是没初始化Random。
给你改好的代码
我把Random初始化加上,还把SendKeys换成了更可靠的Console.Write(毕竟直接写控制台比模拟键盘输入靠谱多了,不用依赖窗口焦点):
// 先把Random对象初始化好,放在类级别全局可用 private static Random rand = new Random(); static void Main(string[] args) { Thread ThreadKeyboard = new Thread(new ThreadStart(RandomKeyboard)); ThreadKeyboard.Start(); // 等待用户输入来终止线程 Console.Read(); ThreadKeyboard.Abort(); } public static void RandomKeyboard() { Console.WriteLine("Random Keyboard Thread Started"); while (true) { char key = (char)(rand.Next(25) + 65); if (rand.Next(2) == 0) { key = char.ToLower(key); } // 直接往控制台写字符,比SendKeys稳定 Console.Write(key); Thread.Sleep(rand.Next(50)); } }
额外给你提个优化建议
Thread.Abort()其实是比较粗暴的终止线程方式,容易搞出资源泄漏之类的问题。更优雅的方式是用一个标志位来控制循环退出,比如这样:
private static Random rand = new Random(); // 用volatile保证多线程下的可见性 private static volatile bool _isRunning = true; static void Main(string[] args) { Thread ThreadKeyboard = new Thread(new ThreadStart(RandomKeyboard)); ThreadKeyboard.Start(); // 等待用户输入后,设置标志位让线程自己退出 Console.Read(); _isRunning = false; ThreadKeyboard.Join(); // 等线程正常结束 } public static void RandomKeyboard() { Console.WriteLine("Random Keyboard Thread Started"); // 用标志位代替while(true) while (_isRunning) { char key = (char)(rand.Next(25) + 65); if (rand.Next(2) == 0) { key = char.ToLower(key); } Console.Write(key); Thread.Sleep(rand.Next(50)); } Console.WriteLine("\nRandom Keyboard Thread Stopped Gracefully"); }
这样线程会自己走完循环再退出,安全多啦~
内容的提问来源于stack exchange,提问作者Zach R
相关产品推荐
相关产品推荐

