Ответ 1
Попробуйте Console.SetCursorPosition
. Подробнее здесь: Как обновить текущую строку в приложении консоли Windows С#?
Использование С# 4 в консольном приложении Windows, которое постоянно сообщает о прогрессе, как я могу сделать "перерисовку" экрана более жидким?
Я хотел бы сделать одно из следующего: - Имейте только "перерисовку" той части экрана, которая изменяется (часть прогресса), и оставляйте остальное как есть. - "Перерисовать" весь экран, но не мигать.
В настоящее время я переписываю весь текст (имя приложения и т.д.). Вот так:
Console.Clear();
WriteTitle();
Console.WriteLine();
Console.WriteLine("Deleting:\t{0} of {1} ({2})".FormatString(count.ToString("N0"), total.ToString("N0"), (count / (decimal)total).ToString("P2")));
Это вызывает много мерцания.
Попробуйте Console.SetCursorPosition
. Подробнее здесь: Как обновить текущую строку в приложении консоли Windows С#?
Я знаю, что этот вопрос немного устарел, но я обнаружил, что если вы установите Console.CursorVisible = false
, то мерцание также прекратится.
static void Main(string[] args)
{
Console.SetCursorPosition(0, 0);
Console.Write("################################");
for (int row = 1; row < 10; row++)
{
Console.SetCursorPosition(0, row);
Console.Write("# #");
}
Console.SetCursorPosition(0, 10);
Console.Write("################################");
int data = 1;
System.Diagnostics.Stopwatch clock = new System.Diagnostics.Stopwatch();
clock.Start();
while (true)
{
data++;
Console.SetCursorPosition(1, 2);
Console.Write("Current Value: " + data.ToString());
Console.SetCursorPosition(1, 3);
Console.Write("Running Time: " + clock.Elapsed.TotalSeconds.ToString());
Thread.Sleep(1000);
}
Console.ReadKey();
}
Вы можете попытаться взломать что-то вместе, используя основные библиотеки.
Вместо того, чтобы тратить время на получение нестандартных результатов, я бы посмотрел этот порт С# библиотеки ncurses (которая является библиотекой, используемой для вывода консольного форматирования):
Я думаю, вы можете использовать \r в консоли Windows, чтобы вернуть начало строки. Вы также можете использовать SetCursorPosition.
Вот простая рабочая демонстрация, показывающая многострочное использование без мерцания. Он показывает текущее время и случайную строку каждую секунду.
private static void StatusUpdate()
{
var whiteSpace = new StringBuilder();
whiteSpace.Append(' ', 10);
var random = new Random();
const string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
var randomWord = new string(Enumerable.Repeat(chars, random.Next(10)).Select(s => s[random.Next(s.Length)]).ToArray());
while (true)
{
Console.SetCursorPosition(0, 0);
var sb = new StringBuilder();
sb.AppendLine($"Program Status:{whiteSpace}");
sb.AppendLine("-------------------------------");
sb.AppendLine($"Last Updated: {DateTime.Now}{whiteSpace}");
sb.AppendLine($"Random Word: {randomWord}{whiteSpace}");
sb.AppendLine("-------------------------------");
Console.Write(sb);
Thread.Sleep(1000);
}
}
В приведенном выше примере предполагается, что окно консоли пуста для запуска. Если нет, обязательно используйте Console.Clear().
Техническое примечание: SetCursorPosition (0,0) помещает курсор в начало (0,0), поэтому следующий вызов Console.Write начнется с строки 0, char 0. Обратите внимание: он не удаляет предыдущее содержимое перед записью. В качестве примера, если вы напишете "asdf" по предыдущей строке, например "0123456", в итоге вы получите что-то вроде "asdf456". По этой причине мы используем переменную whiteSpace, чтобы гарантировать, что любые затяжные символы из предыдущей строки будут перезаписаны пустым пространством. Отрегулируйте длину переменной whiteSpace в соответствии с вашими потребностями. Вам нужна только переменная whiteSpace для строк, которые меняются.
Личное примечание: Для моих целей я хотел показать текущее состояние приложений (один раз в секунду) вместе с кучей другой информации о статусе, и я хотел избежать любого раздражающего мерцания, которое может произойти, когда вы используете Console.Clear(). В моем приложении я запускаю свои обновления статуса за отдельным потоком, поэтому он постоянно предоставляет обновления, даже если у меня есть много других потоков и длительных задач, идущих одновременно.
Кредиты: Благодаря предыдущим плакатам и dtb для генератора случайных строк, используемых в демо. Как я могу генерировать случайные буквенно-цифровые строки в С#?