Рейтинг:
1
Lockwood
Вы можете использовать приложение.DoEvents, чтобы дать потоку пользовательского интерфейса шанс догнать себя.
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
For i As Integer = 1 To 5
System.Threading.Thread.Sleep(1000)
TextBox1.Text = "/"
Application.DoEvents()
System.Threading.Thread.Sleep(1000)
TextBox1.Text = "\"
Application.DoEvents()
Next
End Sub
Я хотел бы сослаться на
Является Ли DoEvents Злом?[
^] или что-то подобное для неизбежных дебатов о том, является ли это хорошей практикой или нет.
Dave Kreskowiak
НЕТ, НЕТ, НЕТ, НЕТ, НЕТ. Приложение.DoEvent-это плохая идея.
Вы должны быть очень осторожны с его использованием, потому что вы можете оказаться в ситуации, когда ваш обработчик событий и любой код, который он запускает, могут быть запущены снова, даже если ваш код не поддерживает/может не поддерживать повторный вход. Это может сделать ваш код болью в заднице для отладки и еще большей болью для репликации проблем, о которых сообщают пользователи.
Я не пользовался им и даже не сталкивался с необходимостью в нем уже 16 лет. В этом нет необходимости, если вы правильно написали свой код.
ИМХО, TPL сделала использование DoEvents непростительным.
Lockwood
Как я уже сказал, это решение, которое заслуживает ссылки на обсуждение его плюсов и минусов.
Для очень простых трюков с потоками пользовательского интерфейса это очень полезный инструмент. для более сложных вещей это не самый безопасный инструмент.
Если OP просто хочет прокрутить какой-то текст на экране по таймеру, DoEvents безопасен, а полная резьба-это перебор. Если ОП хочет сделать больше, чем это, то необходимо рассмотреть другие альтернативы.
Рейтинг:
0
OriginalGriff
Потому что вы говорите потоку пользовательского интерфейса дважды перейти в спящий режим внутри цикла. И пока обработчик событий не завершится, поток пользовательского интерфейса больше ничего не сможет сделать. Поскольку поток пользовательского интерфейса-это то, что изменяет экран и обрабатывает весь пользовательский ввод, ваша форма блокируется до тех пор, пока метод не завершится.
dolfijn3000
ОУ ок это все объясняет но я хочу чтобы он ждал внутри цикла секодн как мне это сделать тогда с замораживанием формы
Dave Kreskowiak
Переместите всю работу в фоновый поток и вызовите метод в форме пользовательского интерфейса, чтобы обновить текстовое поле новым текстом.
private void button1_Click(object sender, EventArgs e)
{
WorkerMethod();
}
protected async void WorkerMethod()
{
Task workerTask = Task.Factory.StartNew(() =>
{
for(int i = 0; i < 5; i++)
{
SetTextBox(@"\");
Thread.Sleep(1000);
SetTextBox(@"/");
Thread.Sleep(1000);
}
});
await workerTask;
SetTextBox(string.Empty);
}
protected void SetTextBox(string message)
{
if (textBox1.InvokeRequired)
{
textBox1.Invoke(new Action(() => SetTextBox(message)));
}
else
{
textBox1.Text = message;
}
}
OriginalGriff
Дэйв, налей себе кофе - он изучает VB! :смеяться:
Dave Kreskowiak
Я терпеть не могу кофе. Хммм... Это могло бы кое-что объяснить.
OriginalGriff
Не на этой нити, а резьба усложняется.
Я бы посоветовал вам использовать таймер для контроля того, когда что - то происходит, вместо того чтобы думать в терминах функционального программирования-Windows полностью управляется событиями, и решение, основанное на событиях, будет намного проще в долгосрочной перспективе.