Console animations

前端 未结 11 1689
误落风尘
误落风尘 2020-12-04 10:15

I just want to know how to create simple animations like blinking, moving stuffs on C# console applications. Is there any special method for this?

11条回答
  •  心在旅途
    2020-12-04 10:41

    I took the anwser from @ThisGuy and modified it a bit, but I noticed, that sometimes the row is not cleared as it should.

        static void Main(string[] args)
        {
            Console.WriteLine("1");
            var tddf = XConsole.BusyIndicator("test 0 trtg fdfdfvdgd 4343", () =>
            {
                return "";
            });
            Console.WriteLine("2");
            var tdd = XConsole.BusyIndicator("test 0 trtg fdfdfvdgd", () =>
            {
                Thread.Sleep(1);
                return "";
            });
            Console.WriteLine("3");
            var t = XConsole.BusyIndicator("test 1 trtg vdgd", () =>
            {
                Thread.Sleep(1000);
                return "";
            });
            Console.WriteLine("4");
            var xt = XConsole.BusyIndicator("test 2", () =>
            {
                Thread.Sleep(2000);
                return "";
            });
            var xtx = XConsole.BusyIndicator("test 2 csds fsd fdsf ds s", () =>
            {
                Thread.Sleep(2000);
                return "";
            });
    
            Console.WriteLine("5");
            Thread.Sleep(4000);
        }
    

    Spinner class:

        public class Spinner : IDisposable
        {
            private const string Sequence1 = @"/-\|";
            private const string Sequence3 = @".o0o";
            private const string Sequence2 = @"<^>v";
            private const string Sequence4 = @"#■.";
            private const string Sequence5 = @"▄▀";
            private const string Sequence = @"└┘┐┌";
            private string BusyMessage = "";
            private int counter = 0;
            private readonly int delay;
            private bool active;
            private readonly Thread thread;
    
            public Spinner(int delay = 200)
            {
                this.delay = delay;
                thread = new Thread(Spin);
            }
    
            public void Start()
            {
                active = true;
                Console.CursorVisible = false;
                if (!thread.IsAlive)
                {
                    thread.Start();
                }
            }
    
            public void Start(string busyMessage)
            {
                BusyMessage = busyMessage;
                Start();
            }
    
            public void Stop()
            {          
                active = false;
                Console.CursorVisible = true;
                ClearCurrentConsoleLine();
                BusyMessage = "";
            }
    
    private static void ClearCurrentConsoleLine()
    {
        int currentLineCursor = Console.CursorTop;
        Console.SetCursorPosition(0, Console.CursorTop);
        Console.Write(new string(' ', Console.WindowWidth));
        Console.SetCursorPosition(0, currentLineCursor);
    }
    
            private void Spin()
            {
                while (active)
                {
                    Turn();
                    Thread.Sleep(delay);
                }
            }
    
            /// 
            /// Draws the busy indicator
            /// 
            /// if empty char, then clear screen
        private void Draw(char c)
        {
            int left = Console.CursorLeft;
            int top = Console.CursorTop;
    
            Console.Write('[');
            Console.ForegroundColor = ConsoleColor.Green;
            Console.Write(c);
            Console.ForegroundColor = ConsoleColor.Gray;
            Console.Write(']');
            if (!string.IsNullOrEmpty(BusyMessage))
            {
                Console.Write(" " + BusyMessage);
            }
    
            //reset cursor position
            Console.SetCursorPosition(left, top);
        }
    
            private void Turn()
            {
                Draw(Sequence[++counter % Sequence.Length]);
            }
    
            public void Dispose()
            {
                Stop();
            }
        }
    

    My console class:

    public static class XConsole {
        public static T BusyIndicator(Func action)
        {
            T result;
    
            using (var spinner = new Spinner())
            {
                spinner.Start();
    
                result = action();
    
                spinner.Stop();
            }
    
            return result;
        }
    
        public static T BusyIndicator(string content, Func action)
        {
            T result;
    
            using (var spinner = new Spinner())
            {
                spinner.Start(content);
    
                result = action();
    
                spinner.Stop();
            }
    
            return result;
        }
    }
    

    Why do I see this result sometimes?

    1
    2
    3   st 0 trtg fdfdfvdgd    ]
    4
    [└] test 2 csds fsd fdsf ds s
    

    Looks like the Dispose didn't trigger? Or a new Task alredy started?

    It should look like this:

    1
    2
    3
    4
    [└] test 2 csds fsd fdsf ds s
    

    UPDATE:

    I added ClearCurrentConsoleLine(); and changed the Draw method, this fixed the issue.

提交回复
热议问题