为什么我的控制台在“窗口”事件发生之前不会关闭?

时间:2009-12-21 04:15:56

标签: c# .net multithreading

我很好奇。我在后台运行它,当我看到控制台消失时,我知道它什么时候完成。我可以点击它查看状态并查看输出。然后我决定添加一个退出按钮。完成后它不再消失(它可以保持活动几分钟或几小时)但是一旦我点击控制台它就会结束。为什么呢?

我写这篇文章是为了展示我的应用程序如何运行的示例。如果你运行它你会发现问题。我使用在Windows 7上运行的msvc 2008编译。

我现在注意到了。它会停止像鼠标移动这样的焦点,失去焦点等事件。等焦点的静止鼠标不会让它退出。为什么?任何解决线程的工作或避免杀死线程而不吃cpu?

-edit-你可以按q退出

using System;
using System.Threading;

namespace ConsoleExitTest
{
    class Program
    {
        static object dummy = new object();
        static bool wantQuit = false;
        static void line() { while (wantQuit == false) { if (Console.ReadKey().Key == ConsoleKey.Q) { wantQuit = true; lock (dummy) { Monitor.Pulse(dummy); }; } } }
        static void Main(string[] args)
        {
            //opt stuff here
            Thread t = new Thread(line); t.Start();
            Console.WriteLine("My code here");

            for (int i = 0; i < 3 && wantQuit == false; i++)
            {
                lock (dummy)
                {
                    Monitor.Wait(dummy, 1000);
                }
            }
            wantQuit = false;
            t.Abort();
        }
    }
}

4 个答案:

答案 0 :(得分:1)

我的猜测是它与Abort处理非托管代码的方式有关。见Complications with Thread.Abort

您可能希望将ReadKey更改为非阻塞方法How to add a Timeout to Console.ReadLine()?,然后您可以在不中止的情况下结束该线程:

wantQuit = true;
t.Join();

答案 1 :(得分:1)

您的帖子在Console.ReadKey()内被阻止,直到您按下某个键。我很惊讶点击窗口可以让它退出。我希望它会被卡住,直到你碰到一把钥匙。

使用Console.KeyAvailable可以让你预先检查按键,这样你就不会阻塞Console.ReadKey(),但是你需要拿出一些其他方法来阻止线程,所以它不是'只是旋转。

答案 2 :(得分:0)

您应该在设计中避免使用Thread.Abort(),因为当线程中止时,它很可能正在执行不应被中断的操作(例如等待控制台输入)。然后,您将遇到各种难以调试的问题。

尝试使用不需要Abort的方法,例如让线程自然退出。这个earlier question对于它为什么是一个问题和可能的替代方案有一些很好的答案。

答案 3 :(得分:0)

解决方法:而不是

wantQuit = false;
t.Abort();

System.Windows.Forms.SendKeys.SendWait("q");