Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > .NET Frameworks (точка нет фреймворки) > C# (си шарп)
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 05.03.2012, 14:49   #1
zonch
 
Регистрация: 24.11.2008
Сообщений: 7
Восклицание Кто сможет объяснить странное поведение таймера?

Люди,хелп.Недавно написал тестовую программу,но мне не понятно поведение таймера.
Цель-есть три прогрессбара,они выполняются последовательно один за другим.Мин значение =0,мах=100.
Инкрементирование значения прогрессбара выполняется в цикле от 1 до 100,с ожиданием методом Thread.Sleep()
Т.к. все выполняется в одном потоке,то после каждого цикла выполняется refresh() формы для прорисовки.
Вопрос-как раз касается метода Thread.Sleep().
Почему-то,если значения таймеров поставить около 30 мс,
то в то время,когда первый прогресс бар еще не заполнился,уже идет заполнение второго и т.д.,
после завершения работы всех (трех) прогрессбаров они дорабатывают до 100 %.
Я думаю,чтобы понять проблему нужно запустить код.Ниже прилагаю код.Формочку нарисуйте сами=)
П.С. Пожалуйста,не пишите сообщения типа "это говонокод" и т.п. Интересует почему некорректно работает именно этот пример.
Код:
namespace nm
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();

        }

        void loading_progressbars(int t1,int t2,int t3)
        {
            
            progressBar1.Minimum=0;
            progressBar1.Maximum=100;
            progressBar1.Value=0;
            progressBar1.Step=1;

            progressBar2.Minimum=0;
            progressBar2.Maximum=100;
            progressBar2.Value=0;
            progressBar2.Step=1;

            progressBar3.Minimum=0;
            progressBar3.Maximum=100;
            progressBar3.Value=0;
            progressBar3.Step=1;
            label1.Visible=true;
			  for (int i=0;i<=100;i++)
            {
                progressBar1.PerformStep();
                Thread.Sleep(t1);
                this.Refresh();
            }
            Thread.Sleep(100);                    // время ожидания после первого прогресс-бара

            label2.Visible=true;
            for (int i=0;i<=100;i++)
            {
                progressBar2.PerformStep();
                Thread.Sleep(t2);
                this.Refresh();
            }
            label5.Visible = true;
            Thread.Sleep(100);                    // время ожидания после 2 прогресс-бара
            label3.Visible=true;
            for (int i=0;i<=100;i++)
            {
                progressBar3.PerformStep();
                Thread.Sleep(t3);
                this.Refresh();
            }
            label4.Visible=true;
            this.Refresh();
            Thread.Sleep(100);                     // время ожидания после 3 прогресс-бара
            return;
        }

        private void Form1_Shown(object sender, EventArgs e)
        {
            loading_progressbars(20, 35, 50);
        }
        
       
    }
}

Последний раз редактировалось Serge_Bliznykov; 05.03.2012 в 15:40.
zonch вне форума Ответить с цитированием
Старый 05.03.2012, 15:39   #2
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,229
По умолчанию

абсолютно ничего не понимаю в вашем примере (как, впрочем, и в программировании под WinForms в C#),
но попробуйте в каждом цикле вставить строчку
Код:
for ...
   Application.DoEvents();
Serge_Bliznykov вне форума Ответить с цитированием
Старый 06.03.2012, 13:12   #3
zonch
 
Регистрация: 24.11.2008
Сообщений: 7
По умолчанию

Цитата:
Сообщение от Serge_Bliznykov Посмотреть сообщение
абсолютно ничего не понимаю в вашем примере (как, впрочем, и в программировании под WinForms в C#),
но попробуйте в каждом цикле вставить строчку
Код:
for ...
   Application.DoEvents();
Я боюсь что данный Sleep создает новый поток и лог не поможет..Тут по c# гуру нет?)
zonch вне форума Ответить с цитированием
Старый 06.03.2012, 13:42   #4
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,229
По умолчанию

Цитата:
Я боюсь что данный Sleep создает новый поток и лог не поможет..
какой лог? Вы о чём?


Цитата:
Тут по c# гуру нет?)
тут есть несколько очень сильных гуру, но, видимо, они сейчас заняты и в данную тему не заходят...
Serge_Bliznykov вне форума Ответить с цитированием
Старый 06.03.2012, 14:27   #5
sergei64_89
Форумчанин
 
Регистрация: 20.04.2008
Сообщений: 139
По умолчанию

когда вы увеличиваете value это не значит что сразу же на интерфейсе полоса увеличивается.скорей всего в этом компоненте это происходит отдельном потоке.
в итоге у вас получается что значение value максимальное а прогрес бар не успел заполниться.
sergei64_89 вне форума Ответить с цитированием
Старый 06.03.2012, 14:33   #6
Скарам
Дружите с Linq ;)
Форумчанин
 
Аватар для Скарам
 
Регистрация: 15.10.2008
Сообщений: 822
По умолчанию

В циклах пиши так
Код:
for (int i = 0; i <= 100; i++)
            {
                progressBar3.PerformStep();
                Application.DoEvents();
                Thread.Sleep(t3);
                this.Refresh();
            }
Пиши так, но это не очень хорошо. Thread.Sleep блокирует нормальное выполнение событий GUI. И получается, что не происходит обновление первого и отработка всех событий отрисовки, а ты после цикла сразу его опять лочишь Sleep-ом, и сразу запускаешь очередной цикл. Вот тебе и результат. Пользуйся потоками.
Не давай организму поблажки, каждый день тренируй его в шашки..
Скарам вне форума Ответить с цитированием
Старый 06.03.2012, 15:21   #7
sergei64_89
Форумчанин
 
Регистрация: 20.04.2008
Сообщений: 139
По умолчанию

ничего не изменилось.как не работало по человечески так и не работает.
а вот относительно потоков,абсолютно согласен.проще запустить отдельный поток в котором изменять позицию прогресс бара,в конце потока сделать слип(для того чтоб прогресбар заполнился до конца),и так далее

Последний раз редактировалось sergei64_89; 06.03.2012 в 15:24.
sergei64_89 вне форума Ответить с цитированием
Старый 06.03.2012, 15:21   #8
zonch
 
Регистрация: 24.11.2008
Сообщений: 7
По умолчанию

Цитата:
Сообщение от Скарам Посмотреть сообщение
В циклах пиши так
Код:
for (int i = 0; i <= 100; i++)
            {
                progressBar3.PerformStep();
                Application.DoEvents();
                Thread.Sleep(t3);
                this.Refresh();
            }
Пиши так, но это не очень хорошо. Thread.Sleep блокирует нормальное выполнение событий GUI. И получается, что не происходит обновление первого и отработка всех событий отрисовки, а ты после цикла сразу его опять лочишь Sleep-ом, и сразу запускаешь очередной цикл. Вот тебе и результат. Пользуйся потоками.
Всем спасибо, в целом я понял проблему)
zonch вне форума Ответить с цитированием
Старый 06.03.2012, 15:28   #9
Скарам
Дружите с Linq ;)
Форумчанин
 
Аватар для Скарам
 
Регистрация: 15.10.2008
Сообщений: 822
По умолчанию

Цитата:
ничего не изменилось.как не работало по человечески так и не работает.
Тогда пользуйся потоками или перед каждым Sleep DoEvents, но это не вариант..
Цитата:
Всем спасибо, в целом я понял проблему)
Рад.)
Не давай организму поблажки, каждый день тренируй его в шашки..
Скарам вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
странное поведение COM метода oldDed C# (си шарп) 2 13.09.2011 17:17
Странное поведение realloc eraserhp Общие вопросы C/C++ 7 17.05.2010 09:52
Странное поведение gets alex_alpha Общие вопросы C/C++ 3 27.03.2010 18:21
Странное поведение процедуры Sergey1974 Общие вопросы Delphi 2 11.12.2009 21:41
Странное поведение DLL Yurk@ Компоненты Delphi 4 01.02.2009 01:23