4

I have a simple WCF-Service that I run in the console when testing it. Sometime I want to have the console windows on top of the other windows so I click it. This activates the "Mark and Paste" command and then freezes the whole application (service becomes unresponsive) until I press enter.

I find that rather annoying.

I don't want to disable the "Mark and Paste", because sometimes I copy text from the console.

Is there any way to detect that the application is frozen?

If I knew when this was the case, I could maybe change the windows titel to display a warning.

EDIT: This is not a duplicate, because I want to know how to handle the freeze and not why it feels frozen. I know now that only the writing to the output is frozen, which causes my application to feel like it is frozen.

flayn
  • 5,272
  • 4
  • 48
  • 69
  • 2
    A *frozen* application can't detect anything. If you want to copy text you'll have to log it – Panagiotis Kanavos Apr 20 '18 at 11:29
  • Possible duplicate of [How and why does QuickEdit mode in Command Prompt freeze applications?](https://stackoverflow.com/questions/30418886/how-and-why-does-quickedit-mode-in-command-prompt-freeze-applications) – RvdK Apr 20 '18 at 11:29
  • @RvdK if, as the duplicate suggests, the only thing that freezes is the *console* a logging library that logs messages in the background, or even one that uses buffering, wouldn't be affected – Panagiotis Kanavos Apr 20 '18 at 11:32
  • @PanagiotisKanavos: It only feels frozen, but it is not actually frozen. Sorry for the confusion, I am reaching the limit of my english capabilities here. Feel free to edit to make is clearer. – flayn Apr 20 '18 at 12:29
  • It is a feature, not a bug. Not otherwise different from the kind of freeze you'd get when you press Ctrl+S. At least configure your console so it is not so easy to trigger it by accident, press Alt+Space > Properties > Options tab > untick "QuickEdit mode". – Hans Passant Apr 20 '18 at 12:43

1 Answers1

4

As explained in this answer, in this mode terminal just stops reading from your application output, which causes your writes to that output (such as Console.WriteLine(...)) to hang.

If you control code that writes to console, you can achieve your goal (change console title when "freeze" is detected) like this:

static async Task WriteLine(string text) {            
    var delay = Task.Delay(TimeSpan.FromSeconds(1));
    var writeTask = Task.Run(() => Console.WriteLine(text));
    var oldTitle = Console.Title;
    if (await Task.WhenAny(delay, writeTask) == delay) {
        // after one second Console.WriteLine still did not return
        // we are probably in "mark and paste" mode
        Console.Title = "FREEZED!";
    }
    // we cannot ignore our write, have to wait anyway
    await writeTask;
    Console.Title = oldTitle;
} 

And using this method instead of regular Console.WriteLine. Of course this is of limited usage, but I think it answers your question.

You can test it with simple:

static async Task Main(string[] args) {
    while (true) {
        await WriteLine("test");
        Thread.Sleep(1000);
    }
}

and observe that console title will change to FREEZED! while you are in that mode, and will change back when you are out of it.

svick
  • 236,525
  • 50
  • 385
  • 514
Evk
  • 98,527
  • 8
  • 141
  • 191
  • I like that a lot, thank you! I will give it a try. The only but: I think in your solution, if the is a lot of stuff written to the console, the order is no longer guaranteed. – flayn Apr 20 '18 at 12:33
  • 1
    @flayn this code is sequential, so order is guaranteed (provided that you always do `await WriteLine("...")`). While it uses `Task.Run` - there is nothing parallel here (note that in the end, `Console.WriteLine` is always awaited with `await writeTask`). – Evk Apr 20 '18 at 12:35