Гость
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / ProgressBar и окончание выполнения / 14 сообщений из 14, страница 1 из 1
16.12.2016, 10:11
    #39368339
Настенька
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ProgressBar и окончание выполнения
Всем доброго дня. Мой вопрос прозвучит странно, но помогите разобраться.

Есть на форме Progressbar1, и кнопка Button1. При нажатии кнопки делаю цикл для примера от 1 до 10 (с засыпанием, чтобы было наглядно виднее), и по окончанию цикла Progressbar1 надо сделать невидимым. Вот код на кнопку:

Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        ProgressBar1.Minimum = 0
        ProgressBar1.Maximum = 10
        ProgressBar1.Value = 0
        For i = 1 To 10
            ProgressBar1.Value = i
            Threading.Thread.Sleep(200)
        Next
        Application.DoEvents()
        Threading.Thread.Sleep(1000)
        ProgressBar1.Visible = False
    End Sub



Проблема в том, что полоса визуально не доходит до конца, и Progressbar1 становится невидимым раньше.
Сразу говорю - потоки и всякие backgroundworker не предлагать. Помогите разобраться ИМЕННО В ЭТОМ КОДЕ. Всем заранее спасибо.
...
Рейтинг: 0 / 0
16.12.2016, 11:39
    #39368438
Roman Mejtes
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ProgressBar и окончание выполнения
Настенька,

Application.DoEvents()

нужно вызвать внутри цикла
...
Рейтинг: 0 / 0
16.12.2016, 11:45
    #39368450
Настенька
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ProgressBar и окончание выполнения
Поставила для гарантии 3 DoEvents - а воз и ныне там. Вот код:

Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        ProgressBar1.Minimum = 0
        ProgressBar1.Maximum = 10
        ProgressBar1.Value = 0
        For i = 1 To 10
            Application.DoEvents()
            ProgressBar1.Value = i
            Application.DoEvents()
            Threading.Thread.Sleep(200)
            Application.DoEvents()
        Next
        Application.DoEvents()
        Threading.Thread.Sleep(1000)
        ProgressBar1.Visible = False
    End Sub



Результат тот же. Попробуйте у себя это и скажите результат.
...
Рейтинг: 0 / 0
16.12.2016, 12:02
    #39368472
Roman Mejtes
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ProgressBar и окончание выполнения
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
        private async void button1_Click(object sender, EventArgs e)
        {
            ProgressBar1.Minimum = 0;
            ProgressBar1.Maximum = 10;
            ProgressBar1.Value = 0;
            for (var i = 0; i < 11; i++)
            {
                Application.DoEvents();
                ProgressBar1.Value = i;
                await Task.Delay(200);
            }
            await Task.Delay(2000);
            ProgressBar1.Visible = false;
        }



у меня вот так работает, какой у вас FW?
...
Рейтинг: 0 / 0
16.12.2016, 12:09
    #39368479
Настенька
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ProgressBar и окончание выполнения
FW 4.0. И ваш код тоже не работает.
Какой FW поставить - чтобы заработало?

Правильно я понимаю (с C# на Vb.net), await Task.Delay(200) = Threading.Thread.Sleep(200)?
...
Рейтинг: 0 / 0
16.12.2016, 12:17
    #39368489
Roman Mejtes
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ProgressBar и окончание выполнения
НастенькаFW 4.0. И ваш код тоже не работает.
Какой FW поставить - чтобы заработало?

Правильно я понимаю (с C# на Vb.net), await Task.Delay(200) = Threading.Thread.Sleep(200)?
неправильно понимаете
Thread.Sleep() приостанавливает текущий поток, в вашем случае это Main Tread (UI поток), потому у вас и не обновляется форма, так как потом отвечающий за её обновление спит в этот момент.
А Task.Delay() создает Task который выполняется в отдельном потоке, а await ожидает его завершения, при этом UI поток не блокируется.
Вообще использовать Thread.Sleep() для таких задач не самая лучшая идея.
...
Рейтинг: 0 / 0
16.12.2016, 12:41
    #39368526
Настенька
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ProgressBar и окончание выполнения
Погуглила, пишут, что аналог C# delay - это sleep.
Тогда вообще ничего не понимаю.

Как вот эту строку await Task.Delay(200); правильно написать на Vb???
...
Рейтинг: 0 / 0
16.12.2016, 15:53
    #39368763
ЕвгенийВ
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ProgressBar и окончание выполнения
НастенькаПогуглила, пишут, что аналог C# delay - это sleep.
Тогда вообще ничего не понимаю.

Как вот эту строку await Task.Delay(200); правильно написать на Vb???
На 4,0 никак.
...
Рейтинг: 0 / 0
16.12.2016, 19:42
    #39368980
VSVLAD
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ProgressBar и окончание выполнения
Настенька,

На 4.5 можно использовать Async/Await. В вашем случае (на Win7 как минимум) код в таком виде, как он есть, логически не будет работать правильно. После присваивания значения ProgressBar нужно время, чтобы элемент отрисовал анимацию заполнения. Sleep напрочь блокирует поток, а DoEvents лишь даёт возможность сообщению "отрисоваться" дойти до назначения, до контрола, а время на отрисовку уже не будет, происходит выход из цикла и сокрытие контрола с экрана. Нужна задержка, например такая:

Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
	ProgressBar1.Minimum = 0
	ProgressBar1.Maximum = 10
	ProgressBar1.Value = 0

	For I = 1 To 11
		If ProgressBar1.Value < ProgressBar1.Maximum Then
			ProgressBar1.Value = I
			ProgressBar1.Invalidate()

			Threading.Thread.Sleep(200)
		Else
			Dim tm As Long = Now.Ticks + 5000000 '0.5 сек
			While tm > Now.Ticks
				Application.DoEvents()
			End While

			ProgressBar1.Visible = False
		End If
	Next
End Sub
...
Рейтинг: 0 / 0
16.12.2016, 23:10
    #39369057
Roman Mejtes
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ProgressBar и окончание выполнения
в 4.0 есть TPL и таски используйте их
...
Рейтинг: 0 / 0
17.12.2016, 10:30
    #39369164
Cat2
Модератор форума
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ProgressBar и окончание выполнения
Настенька
Код: vbnet
1.
2.
3.
4.
ProgressBar1.Refresh()

Threading.Thread.Sleep(1000)
ProgressBar1.Visible = False
...
Рейтинг: 0 / 0
17.12.2016, 10:34
    #39369166
Cat2
Модератор форума
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ProgressBar и окончание выполнения
VSVLADНастенька,

На 4.5 можно использовать Async/Await. В вашем случае (на Win7 как минимум) код в таком виде, как он есть, логически не будет работать правильно. После присваивания значения ProgressBar нужно время, чтобы элемент отрисовал анимацию заполнения. Sleep напрочь блокирует поток, а DoEvents лишь даёт возможность сообщению "отрисоваться" дойти до назначения, до контрола, а время на отрисовку уже не будет, происходит выход из цикла и сокрытие контрола с экрана. Нужна задержка, например такая:

Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
	ProgressBar1.Minimum = 0
	ProgressBar1.Maximum = 10
	ProgressBar1.Value = 0

	For I = 1 To 11
		If ProgressBar1.Value < ProgressBar1.Maximum Then
			ProgressBar1.Value = I
			ProgressBar1.Invalidate()

			Threading.Thread.Sleep(200)
		Else
			Dim tm As Long = Now.Ticks + 5000000 '0.5 сек
			While tm > Now.Ticks
				Application.DoEvents()
			End While

			ProgressBar1.Visible = False
		End If
	Next
End Sub


Избыточно. У ТС не перерисовывается только завершение
...
Рейтинг: 0 / 0
18.12.2016, 13:53
    #39369557
VSVLAD
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ProgressBar и окончание выполнения
Cat2VSVLAD...Избыточно. У ТС не перерисовывается только завершение
По крайней мере работает, через ProgressBar1.Refresh() ведёт себя также, концовка не перерисовывается
...
Рейтинг: 0 / 0
19.12.2016, 05:24
    #39369762
Настенька
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ProgressBar и окончание выполнения
Cat2, переделала вот так, теперь все работает супер. Огромное спасибо.

Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
ProgressBar1.Minimum = 0
        ProgressBar1.Maximum = 10
        ProgressBar1.Value = 0
        ProgressBar1.Visible = True
        For I = 1 To 10
            ProgressBar1.Value = I
            Threading.Thread.Sleep(200)
        Next
        Dim tm As Long = Now.Ticks + 5000000 '0.5 сек
        While tm > Now.Ticks
            Application.DoEvents()
        End While
        ProgressBar1.Visible = False
...
Рейтинг: 0 / 0
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / ProgressBar и окончание выполнения / 14 сообщений из 14, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]