views:

65

answers:

4

I am curious. I run this in the background and i know when its done when i see the console disappear. I can check the status by clicking on it and see the output. Then i decided to add a quit button. It no longer disappears when done (it can stay alive for minutes or hours) but once i click on the console it ends. Why?

I wrote this to show an example of how my app runs. If you run it you'll notice the problem. I compiled with msvc 2008 running on windows 7.

I notice now. It quits on an event like focus like mouse move, on of lose focus. etc. A still mouse on focus will not make it quit. Why? Any work around to killing the thread or avoid killing the thread and not eat cpu?

-edit- you can press q to quit

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();
        }
    }
}
+1  A: 

My guess would be its to do with the way Abort works with unmanaged code. See Complications with Thread.Abort.

You may want to change the ReadKey to a non blocking method How to add a Timeout to Console.ReadLine()? and then you can end the thread without Abort:

wantQuit = true;
t.Join();
Courtney de Lautour
+1  A: 

Your thread is blocked inside Console.ReadKey() until you hit a key. I'm surprised that clicking on the window allows it to quit. I'd expect it to be stuck until you actually hit a key.

using Console.KeyAvailable would let you pre-check for a keystroke so you wouldn't block in Console.ReadKey(), but then you need to come up with some other way to block the thread so it isn't just spinning.

John Knoeller
A: 

You should avoid Thread.Abort() in your design because when a thread is aborted it is quite possible that it is performing an action that should not be interrupted (such as waiting for Console input). You will then run into all sorts of hard to debug issues.

Try using an approach that doesn't require the Abort such as letting the thread exit naturally. This earlier question has some good answers as to why it is a problem and possible alternatives.

Ash
A: 

Workaround: Instead of

wantQuit = false;
t.Abort();

Write

System.Windows.Forms.SendKeys.SendWait("q");
acidzombie24
This seemed to work but now it seems to put q in my current window.
acidzombie24