Keep Console.ReadLine always on last line

后端 未结 3 1611
别跟我提以往
别跟我提以往 2021-01-23 03:44

I have an application written in C# which takes continuously commands from the user via a while(true) loop and Console.ReadLine.

I also do have various background operat

相关标签:
3条回答
  • 2021-01-23 04:19

    This is very, very difficult to do. You end up writing your own console input and output methods that every thread has to call. If any thread doesn't cooperate, it just doesn't work right. But it's possible using the Console API.

    The basic idea is to have your common output function write to the console screen buffer, and scroll the buffer in code rather than letting the text flow onto the last line and scroll automatically. As I recall, you'll have to parse the output for newlines and other control characters, and handle them correctly.

    You might be able to get away with using Console.ReadLine on the last line, although in doing so you risk problems if the user enters more text than will fit on a single line. Also, the user hitting Enter at the end of the line might cause it to scroll up. Probably best in this situation to use raw console input.

    You'll want to become very familiar with Windows consoles.

    Be forewarned: it's a lot of work. And probably not worth the effort.

    0 讨论(0)
  • 2021-01-23 04:21

    Just an idea. You can use the Console.CursorTop and Console.CursorLeft properties.

    class Program
    {
        static void Main(string[] args)
        {
            new Messager(1000 * 2.5f);
            new Messager(1000 * 3);
    
            while (true)
            {
                Console.CursorTop = 0;
                Console.ReadLine();
            }
        }
    }
    
    public class Messager
    {
        Timer Timer;
    
        static int position = 1;
    
        public Messager(double interval)
        {
            this.Timer = new Timer(interval);
    
            this.Timer.Elapsed += (sender, e) =>
            {
                lock (this)
                {
                    var cursorLeft = Console.CursorLeft;
                    Console.CursorLeft = 0;
                    Console.CursorTop = position++;
                    Console.WriteLine("message from " + this.Timer.Interval);
                    Console.CursorTop = 0;
                    Console.CursorLeft = cursorLeft;
                }
            };
    
            this.Timer.Start();
        }
    }
    
    0 讨论(0)
  • 2021-01-23 04:38

    Here's the answer to my problem:

    class Program
    {
        static void Main(string[] args)
        {
            new Messager(1000 * 2.5f);
            new Messager(1000 * 3);
            while (true)
            {
                Console.ReadLine();
            }
        }
    }
    
    public class Messager
    {
        Timer Timer;
    
        public Messager(double interval)
        {
            this.Timer = new Timer(interval);
            this.Timer.Elapsed += (sender, e) =>
            {
                int currentTopCursor = Console.CursorTop;
                int currentLeftCursor = Console.CursorLeft;
    
                Console.MoveBufferArea(0, currentTopCursor, Console.WindowWidth, 1, 0, currentTopCursor + 1);
    
                Console.CursorTop = currentTopCursor;
    
                Console.CursorLeft = 0;
    
                Console.WriteLine("message from " + this.Timer.Interval);
    
                Console.CursorTop = currentTopCursor +1;
                Console.CursorLeft = currentLeftCursor;
    
            };
            this.Timer.Start();
        }
    }
    
    0 讨论(0)
提交回复
热议问题