powered by simpleCommunicator - 2.0.56     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Не отображается отрисовка progressbar из отдельного потока
14 сообщений из 14, страница 1 из 1
Не отображается отрисовка progressbar из отдельного потока
    #38469554
BRS_1
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Подскажите пожалуйста.
Немогу разобраться, почему не отображается отрисовка прогрессбара из отдельного потока.
Странно, но метод "updadeBar" получает управление только в самом конце - когда уже отработает цикл эмуляции вычислений.

Framework 4


Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
public delegate void Update(int value);      

public void updadingThread(object sender)
        {
            Update update = new Update(updadeBar);
            for (int i = 0; i <= 100; i++)
            {
                this.progbar.BeginInvoke(update, new object[] { i });
                System.Threading.Thread.Sleep(50);
            }
        }

public void updadeBar(int value)
        {            
            this.progbar.Value = value;            
            //MessageBox.Show("111");       
        }


private void button3_Click(object sender, EventArgs e)
        {
            cb_splitters.Enabled = false;
            button1.Enabled = false;
            button2.Enabled = false;

            Thread th = new Thread(updadingThread);
            th.Start();

            //----------------------------------------------------
            //эмуляция вычислений (30-40 сек)
            //Thread.Sleep(60000);
            for (int i = 0; i < 99999999; i++)
            {
                string s = i.ToString();
                s = s.Length.ToString() + " " + i.ToString();
            }
            //----------------------------------------------------

            th.Abort();

            cb_splitters.Enabled = true;
            button1.Enabled = true;
            button2.Enabled = true;
        }
...
Рейтинг: 0 / 0
Не отображается отрисовка progressbar из отдельного потока
    #38469647
Sergey TSV
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
BRS_1
Код: c#
1.
2.
3.
...
  this.progbar.BeginInvoke(update, new object[] { i });
...



Все правильно.
Из МСДН :
BeginInvoke(Delegate, Object[]) - Выполняет указанный делегат асинхронно с указанными аргументами в потоке, в котором был создан базовый дескриптор элемента управления.

А тот поток занят вычислениями...
...
Рейтинг: 0 / 0
Не отображается отрисовка progressbar из отдельного потока
    #38469679
BRS_1
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Как тогда реализовать изменение прогрессбара?
...
Рейтинг: 0 / 0
Не отображается отрисовка progressbar из отдельного потока
    #38469682
Sergey TSV
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
BRS_1,

Изначально решение задачи неверно выбрано. Вы выполняете вычисление в UI-потоке, а управляете элементами управления из рабочих потоков. Сделайте наоборот.
...
Рейтинг: 0 / 0
Не отображается отрисовка progressbar из отдельного потока
    #38469683
Pallaris
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BRS_1Как тогда реализовать изменение прогрессбара?

Делать вычисления в другом потоке.
...
Рейтинг: 0 / 0
Не отображается отрисовка progressbar из отдельного потока
    #38469737
LameUser
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BRS_1,
Если вам не так важно вычисление данных в другом потоке - попробуйте
Код: c#
1.
Application.DoEvents();


тынц

В вашем случае порекомендую BackgroundWorker , на моей практике покрывал потребности до 70% простых задач, где требовалась отрисовка progressbar.

А так да, вычисления нужно делать в другом потоке (не в UI)
...
Рейтинг: 0 / 0
Не отображается отрисовка progressbar из отдельного потока
    #38469796
BRS_1
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
[quot Pallaris]BRS_1Как тогда реализовать изменение прогрессбара?

Не вопрос. Вопрос - как узнать, что вычисления вычислились (что бы отключить прогрессбар)?

Попытка №1 (через событие)

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
private  delegate void StopThread();                      
private  event StopThread OnStopThread;

private void Emul_Math()
        {            
                for (int i = 0; i < 99999999; i++)
                {
                    string s = i.ToString();
                    s = s.Length.ToString() + " " + i.ToString();
                }
            
            OnStopThread();     //вызов события по завершению вычислений
        }

private void ZZZ()
        {            
                progbar.Style = ProgressBarStyle.Blocks;   //<--- тут вылезет ошибка
                cb_splitters.Enabled = true;
                button1.Enabled = true;
                button2.Enabled = true;            
        }


private void button4_Click(object sender, EventArgs e)
        {
            cb_splitters.Enabled = false;
            button1.Enabled = false;
            button2.Enabled = false;
            progbar.Style = ProgressBarStyle.Marquee;

            OnStopThread += new StopThread(ZZZ);

            Thread th_new = new Thread(Emul_Math);
            th_new.Start();
        }



Результат - прогресс бар крутится пока не сработает событие и вот тогда получаю ошибку - Недопустимая операция в нескольких потоках: попытка доступа к элементу управления 'progbar' не из того потока, в котором он был создан.



Попытка №2 (через блокировку)

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
object locker = new object();

private void Emul_Math()
        {
            lock (locker)
            {
                for (int i = 0; i < 99999999; i++)
                {
                    string s = i.ToString();
                    s = s.Length.ToString() + " " + i.ToString();
                }
            }            
        }


        private void ZZZ()
        {
            lock (locker)
            {
                progbar.Style = ProgressBarStyle.Blocks;
                cb_splitters.Enabled = true;
                button1.Enabled = true;
                button2.Enabled = true;
            }
        }


private void button4_Click(object sender, EventArgs e)
        {
            cb_splitters.Enabled = false;
            button1.Enabled = false;
            button2.Enabled = false;
            progbar.Style = ProgressBarStyle.Marquee;

            Thread th_new = new Thread(Emul_Math);
            th_new.Start();

            Thread.Sleep(100);
            ZZZ();      
        }




Результат - прогресс бар не отображается, с таким же успехом можно было вместо вызова метода "ZZZ"
вызвать th_new.Join();
...
Рейтинг: 0 / 0
Не отображается отрисовка progressbar из отдельного потока
    #38469867
BRS_1
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
LameUserBRS_1,
Если вам не так важно вычисление данных в другом потоке - попробуйте
Код: c#
1.
Application.DoEvents();


тынц

В вашем случае порекомендую BackgroundWorker , на моей практике покрывал потребности до 70% простых задач, где требовалась отрисовка progressbar.

А так да, вычисления нужно делать в другом потоке (не в UI)




Попытка №3 с backgroundworker

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
private void button5_Click(object sender, EventArgs e)
        {
            progbar.Style = ProgressBarStyle.Blocks;
            cb_splitters.Enabled = false;
            button1.Enabled = false;
            button2.Enabled = false;

            backgroundWorker1.RunWorkerAsync();   //вызвали
        }

        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            //эмулятор нагрузки
            for (int i = 0; i < 99999999; i++)
            {
                string s = i.ToString();
                s = s.Length.ToString() + " " + i.ToString();
            }
        }

        private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            progbar.Style = ProgressBarStyle.Blocks;
            cb_splitters.Enabled = true;
            button1.Enabled = true;
            button2.Enabled = true;
        }




Результат - прогресс бар не отображается. Скорее всего потому, что я не вызываю "ReportProgress"
Вызывать его неоткуда, т.к. на самом деле никаких циклов в моих вычисления нет, вместо цикла

Код: c#
1.
for (int i = 0; i < 99999999; i++)



вызывается метод из другой подключенной бибилиотеки.
...
Рейтинг: 0 / 0
Не отображается отрисовка progressbar из отдельного потока
    #38469892
LameUser
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BRS_1,

Не вижу подписок на события bworkerа:
backgroundWorker1_DoWork и backgroundWorker1_RunWorkerCompleted

Попробуйте пример отсюда http://www.codeproject.com/Tips/83317/BackgroundWorker-and-ProgressBar-demo
...
Рейтинг: 0 / 0
Не отображается отрисовка progressbar из отдельного потока
    #38469974
BRS_1
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
LameUserBRS_1,

Не вижу подписок на события bworkerа:
backgroundWorker1_DoWork и backgroundWorker1_RunWorkerCompleted

Попробуйте пример отсюда http://www.codeproject.com/Tips/83317/BackgroundWorker-and-ProgressBar-demo


Подписки есть, они в файле *.Designer.cs

Код: c#
1.
2.
3.
4.
5.
6.
7.
// 
// backgroundWorker1
// 
this.backgroundWorker1.WorkerReportsProgress = true;
this.backgroundWorker1.WorkerSupportsCancellation = true;
this.backgroundWorker1.DoWork += new System.ComponentModel.DoWorkEventHandler(this.backgroundWorker1_DoWork);            
this.backgroundWorker1.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(this.backgroundWorker1_RunWorkerCompleted);




За пример благодарю, мой код по смыслу такой же.
Разве что

Код: c#
1.
backgroundWorker1.ReportProgress(i);



мне вызывать на самом деле неоткуда.
...
Рейтинг: 0 / 0
Не отображается отрисовка progressbar из отдельного потока
    #38470201
BRS_1
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Опечатка была в коде обработчика button5_Click (progbar.Style = ProgressBarStyle.Blocks)
правильный код:


Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
private void button5_Click(object sender, EventArgs e)
        {
            progbar.Style = ProgressBarStyle.Marquee;    //<------ так правильно
            cb_splitters.Enabled = false;
            button1.Enabled = false;
            button2.Enabled = false;

            backgroundWorker1.RunWorkerAsync();   //вызвали
        }

        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            for (int i = 0; i < 99999999; i++)
            {
                string s = i.ToString();
                s = s.Length.ToString() + " " + i.ToString();
            }
        }

        private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            progbar.Style = ProgressBarStyle.Blocks;    //<--- отключили прогрессбар
            cb_splitters.Enabled = true;
            button1.Enabled = true;
            button2.Enabled = true;
        }




Прогрессбар отображается, всем откликнувшимся благодрности!

ПН. "ReportProgress" - не при чем :)
...
Рейтинг: 0 / 0
Не отображается отрисовка progressbar из отдельного потока
    #38470813
sld
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
sld
Гость
ну сейчас у тебя бегает бесцельная фигня, которая единственно отображает что у тебя поток запущен и ещё не завершился.
а при использовании ReportProgress ты мог бы видеть сколько примерно циклов у тебя обработано.
...
Рейтинг: 0 / 0
Не отображается отрисовка progressbar из отдельного потока
    #38471673
BRS_1
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
sldну сейчас у тебя бегает бесцельная фигня

так и задумывалось
...
Рейтинг: 0 / 0
Не отображается отрисовка progressbar из отдельного потока
    #38471693
BRS_1
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
подсказали еще способ, можно обойтись без BackgroundWorker
может кому пригодится:

Попытка №4 (с блекджеком потоками и Invoke)


Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
private void Emul_Math()
        {
            for (int i = 0; i < 99999999; i++)
            {
                string s = i.ToString();
                s = s.Length.ToString() + " " + i.ToString();
            }

            this.Invoke(new Action(() =>
            {
                progbar.Style = ProgressBarStyle.Blocks; 
                cb_splitters.Enabled = true;
                button1.Enabled = true;
                button2.Enabled = true;
            }));
        }

        private void button3_Click(object sender, EventArgs e)
        {
            progbar.Style = ProgressBarStyle.Marquee;
            cb_splitters.Enabled = false;
            button1.Enabled = false;
            button2.Enabled = false;

            Thread th = new Thread(Emul_Math);     
            th.Start();
        }




Результат - работает
...
Рейтинг: 0 / 0
14 сообщений из 14, страница 1 из 1
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Не отображается отрисовка progressbar из отдельного потока
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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