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?
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.