Console selection stops application
Asked Answered
S

2

7

I'm running a socket server on my server and I woke up to messages about its inaccessibility. It turns out that before I went to bed, I had selected text in the window. I forgot to hit Enter to resume the process.

This is how I disable selection in the console, now, but I still want to be able to select without the application pausing.

    #region Disable Quick-Edit Mode
    [DllImport("kernel32.dll")]
    static extern bool SetConsoleMode(IntPtr hConsoleHandle, int mode);

    [DllImport("kernel32.dll")]
    static extern bool GetConsoleMode(IntPtr hConsoleHandle, out int mode);

    [DllImport("kernel32.dll")]
    static extern IntPtr GetStdHandle(int handle);

    const int STD_INPUT_HANDLE = -10;
    const int ENABLE_EXTENDED_FLAGS = 0x80;
    
    public static void DisableQuickEditMode()
    {
        int mode;
        IntPtr handle = GetStdHandle(STD_INPUT_HANDLE);
        GetConsoleMode(handle, out mode);
        mode |= ENABLE_EXTENDED_FLAGS;
        SetConsoleMode(handle, mode);
        mode &= ~ENABLE_QUICK_EDIT;
        SetConsoleMode(handle, mode);
    }

I really don't want to go back to the Legacy Mode of Command Prompt, because it really does help to have the new console features, but I need to find a way to prevent the application from stopping when I pause the console.

What's interesting is that when I hit Enter this morning, all of the connections that had been attempted were accepted, and then after they were un-queued, they were dropped. Which makes me wonder if, perhaps, I'm writing the application wrong; that I need to have a "Console" thread and a "Server" thread. I'm not sure that could even make a difference.

Shick answered 2/11, 2016 at 17:23 Comment(2)
This happens to every console program running on Windows, and is simply a consequence of your selection preventing new output from being displayed, which in turn eventually prevents calls like Console.WriteLine() from completing, because the output buffer is full. This question has nothing to do with programming; it's a basic WIndows user topic.Sporran
Oh I'm sorry. I never realized that was the case; I don't use console apps very often and I just assumed that most programmers had a hack for it. Pardon.Shick
M
7

When in selection mode, any thread in the Windows console will block when writing stdout or stderr. Doesn't matter which thread.

You could separate out the console writes from the server operations and make sure the server threads never write to the console, but then you introduce additional thread management and message queueing concerns.

You could do what most people do: Use log files. If you don't want to build file writing into the application, just pipe stdout and stderr to a file and use some Windows equivalent of tail to monitor the file (or a text editor like Sublime which automatically monitors open files).

server.exe > server.log 2>&1

To clarify: 2>&1 indicates that stderr (file handle 2) should be "merged into" stdout (file handle 1).

Mandeville answered 2/11, 2016 at 17:42 Comment(0)
B
1

For simple tools, executing the Console writes in a different thread may indeed be easiest. Sample code:

    static BlockingCollection<string> messageQueue = new BlockingCollection<string>(new ConcurrentQueue<string>());
    static Task messagePrinterTask;
    private static void ConsoleWriteLine(string s)
    {
        messageQueue.Add(s);
    }
    private static void StartMessageQueuePrinter()
    {
        messagePrinterTask = Task.Run(() =>
        {
            try { while(true) Console.WriteLine(messageQueue.Take()); }
            catch (InvalidOperationException) { } //CompleteAdding called.
        });
    }
    private static void StopMessageQueuePrinter()
    {
        messageQueue.CompleteAdding();
        messagePrinterTask.Wait();
    }
Boiling answered 11/9, 2019 at 8:50 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.