littleguga
@littleguga
Не стыдно не знать, а стыдно не интересоваться.

Как реализовать «бегающие» точки?

Хочется сделать свое отображение ожидания процесса.
Должно выглядеть так: 1) .
2) ..
3) ...
4) .
И так в цикле.
Вопрос, как реализовать это на c#?
В голову пришло такое, но при запуске форма зависает и не реагирует:
int i = 0;
int k = 0;
while (i < 1000)
{
	if (k == 0)
	{
		label1.Text = ".";
		k = 1;
	}
	else if (k == 1)
	{
		label1.Text = "..";
		k = 2;
	}
	else
	{
		label1.Text = "..";
		k = 0;
	}
		Thread.Sleep(100);
		i++;
}


ps.
В самой задаче уже отказался от этой затеи в пользу ProgressBar'a с Style=Marquee. Но вопрос теперь носит чисто академический интерес.

pps.
Уверен, что где-то в мире это уже реализовано. Но честно говоря я даже не знаю, как сформулировать вопрос "по-человечески", поэтому и погуглить не смог.
  • Вопрос задан
  • 2629 просмотров
Решения вопроса 3
SHVV
@SHVV
Если у вас этот код вызывается в потоке пользовательского интерфейса, то ничего удивительного в этом нет. Вы блокируете обработку очереди сообщений и не даёте контролам даже перерисовать себя.

В "хороших" приложениях блокировать UI не стоит, нужно переносить код в параллельный поток, а оттуда обновлять контролы.
Но в крайнем случае, можно просто периодически давать "просраться" очереди сообщений с помощью Application.DoEvents().
Ответ написан
Вызов Thread.Sleep(100) "вешает" ваш UI поток.

Вам нужно обновлять Label.Text асинхронно. В WinForms это можно сделать с помощью BackgroundWorker. Например:
  1. добавить на форму BackgroundWorker (допустим это будет дефолтовый backgroundWorker1)
  2. добавить необходимый код в его backgroundWorker1_DoWork()
  3. сделать вызов backgroundWorker1.RunWorkerAsync() из UI треда

Более подробно смотрите на MSDN.
Ответ написан
Nipheris
@Nipheris Куратор тега C#
Вопрос действительно академический: вам нужно основательно разобраться с событийно-управляемой (event-driven) архитектурой приложений. Пожалуй, все современные графические подсистемы так или иначе построены на ней (а вообще - не только графические). И в первую очередь нужно понять, что выполнение действий в своем цикле без передачи управления обработчикам сообщений - неверный подход. Дело в том, что GUI-приложение, в отличие от консольного, для того чтобы "не зависать", должно постоянно выполнять некоторые действия помимо нужных для вашей задачи, а именно - перерисовываться, обрабатывать события клавиатуры и мыши и т.д. Изза того что ваша программа "крутится" в цикле, то все те стандартные обработчики событий, которые должны получать управление, не получают его. Поэтому, если нужно выполнять интенсивные вычисления в графическом приложении, нужно либо:
а) выполнять их в другом потоке - тогда получится сохранить структуру приложения и циклы, но встанет задача межпоточной передачи данных;
б) выполнять работу порционно, время от времени передавая управления обработчикам системных событий. Это т.н. вызов DoEvents, в разных API он разный, но суть одна и та же.

Конкретно для вашей задачи цикл на самом деле совершенно не нужен - вся анимация, какой бы они ни была, в современных приложениях (старые DOSовские игры не в счет) строится на таймерах и событиях их срабатывания. Поэтому вам нужно разобраться, как пользоваться в вашей среде таймерами и генерировать периодические события, и уже в обработчике события таймера делать label1.Text = "." , ".." , "..." в зависимости от того, какой "кадр" был предыдущий.
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы