Форум программистов, компьютерный форум, киберфорум
C# .NET
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.61/18: Рейтинг темы: голосов - 18, средняя оценка - 4.61
0 / 0 / 0
Регистрация: 13.01.2010
Сообщений: 35

ProgressBar не хочет работать из потока

07.01.2012, 20:43. Показов 3521. Ответов 16
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
помогите пожалуйста, не пойму что делаю не так, на форму закинуты прогрессбар и 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
28
29
30
31
private void CalcBtn_Click(object sender, EventArgs e)
        {
            backgroundWorker1.RunWorkerAsync();
           
        }
       
        public void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            for (int i = 0; i < 100; i++)
            {
 
               /////данный кусок должен остаться неизменным
                CFirDoc p = new CFirDoc(id);               
                double TotalSeconds = p.Go();
                Form1.cdoc = p;
                ////
                
 
                backgroundWorker1.ReportProgress(i);
            }           
        }
 
        private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            progressBar1.Value = e.ProgressPercentage;
        }
 
        public void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            MessageBox.Show("Работа завершена");
        }
и вроде как операция выполняется, но прогрессбар остается неподвижным, при этом если написать
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
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            for (int i = 0; i < 100; i++)
            {
                ///вместо необходимого моего куска
                for (int j = 0; j < 10000000; j++) ;
 
 
                backgroundWorker1.ReportProgress(i);                               
            }
        }
 
        private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            progressBar1.Value = e.ProgressPercentage;
        }
 
       
        private void button1_Click(object sender, EventArgs e)
        {
            backgroundWorker1.RunWorkerAsync();
        }
 
        private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            
                MessageBox.Show("Работа завершена");
        }
то все работает и прогрессбар движется? что я делаю не так?
или может лучше использовать
C#
1
2
 var thread = new Thread();
            thread.Start();
но как тогда в новом потоке правильно запустить
C#
1
2
3
CFirDoc p = new CFirDoc(id);               
                double TotalSeconds = p.Go();
                Form1.cdoc = p;
и прикрутить к нему прогрессбар?

не отправляйте пожалуйста к литературе, уже было много перечитано, но что-то ничего не помогает
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
07.01.2012, 20:43
Ответы с готовыми решениями:

Как работать с progressbar из другого потока
Сразу после начала работы программы вылетает такая ошибка &quot;Дополнительные сведения: Вызывающий поток не может получить доступ к данному...

Интернет не хочет работать,все хорошо подключается а браузер открывать не хочет первую страницу отображает
ребят такой вопрос,установил винду 8,все норм только интернет не хочет работать,все хорошо подключается а браузер открывать не хочет первую...

Обновление ProgressBar из основного потока
Здравствуйте! Итак, имеется долго выполняющийся код , внутри которого время от времени должно обновляться значение ProgressBar. Следом...

16
Эксперт .NET
 Аватар для kolorotur
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
07.01.2012, 20:48
У вас цикл заканчивается так быстро, что прогресс не успевает отрисовываться.
Это - первый признак в отсутствии надобности использования индикатора прогресса.
0
0 / 0 / 0
Регистрация: 13.01.2010
Сообщений: 35
07.01.2012, 20:51  [ТС]
Цитата Сообщение от kolorotur Посмотреть сообщение
У вас цикл заканчивается так быстро, что прогресс не успевает отрисовываться.
цикл не заканчивается быстро эти 3 строчки кода
C#
1
2
3
CFirDoc p = new CFirDoc(id);               
                double TotalSeconds = p.Go();
                Form1.cdoc = p;
в самом лучшем случае расчитываются минуты 4
0
79 / 79 / 12
Регистрация: 07.01.2012
Сообщений: 167
09.01.2012, 02:16
C#
1
2
3
4
5
6
7
8
9
private void button1_Click(object sender, EventArgs e)
        {
            backgroundWorker1.RunWorkerAsync();
            while (backgroundWorker1.IsBusy)
            {
                progressBar1.Increment(1);
                Application.DoEvents();
            }
}
Добавлено через 1 минуту
так он работает не из потока, но дает статус потока
1
MiThEoN
 Аватар для VASSUV
466 / 323 / 42
Регистрация: 31.10.2009
Сообщений: 546
Записей в блоге: 2
09.01.2012, 08:58
Цитата Сообщение от Villiya Посмотреть сообщение
вроде как операция выполняется, но прогрессбар остается неподвижным
У меня похожая штука была на visual studio, только с трэкбаром.
на самом деле все просто было. В режиме отладки не подвижным остается. А когда запускаешь exe-ку из bin\debug - тогжа все работает
1
 Аватар для hotkey
19 / 17 / 5
Регистрация: 06.09.2011
Сообщений: 51
09.01.2012, 13:57
попробуйте
C#
1
backgroundWorker1.WorkerReportsProgress = true;
1
0 / 0 / 0
Регистрация: 13.01.2010
Сообщений: 35
09.01.2012, 21:49  [ТС]
Цитата Сообщение от Talent Посмотреть сообщение
C#
1
2
3
4
5
6
7
8
9
private void button1_Click(object sender, EventArgs e)
        {
            backgroundWorker1.RunWorkerAsync();
            while (backgroundWorker1.IsBusy)
            {
                progressBar1.Increment(1);
                Application.DoEvents();
            }
}
Добавлено через 1 минуту
так он работает не из потока, но дает статус потока
если так, то прогрессбар при запуске "заполняется" очень быстро и останавливается, при этом процесс продолжает работать в фоне т.е. прогрессбар реально не отображает ход выполнения

Добавлено через 4 минуты
Цитата Сообщение от VASSUV Посмотреть сообщение
У меня похожая штука была на visual studio, только с трэкбаром.
на самом деле все просто было. В режиме отладки не подвижным остается. А когда запускаешь exe-ку из bin\debug - тогжа все работает
да, попробовала та запустить вроде процесс в прогрессбаре отображается, но только почему-то ОЧЕНЬ медленно, если так время растеза занимало минуты 4-5, то сейчас минут 20 и то за это время процесс выполняется только процентов на 15, есть ли возможность ускорить этот процесс?

Добавлено через 58 минут
возможно ли для данного случая использовать ThreadPool? если да, то каким образом будет выглядеть код? что-то типа такого?
C#
1
2
3
4
5
6
7
8
9
10
11
private void CalcBtn_Click(object sender, EventArgs e)
        {
           ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadProc));
           
        }
 static void ThreadProc(Object stateInfo) 
{
        CFirDoc p = new CFirDoc(id);               
                double TotalSeconds = p.Go();
                Form1.cdoc = p;
    }
но как тогда в этом случае отобразить ход вычислений на прогрессбаре? и вообще сообщить пользователю что вычисления закончены?
0
 Аватар для Димон_
136 / 104 / 9
Регистрация: 30.01.2011
Сообщений: 699
09.01.2012, 21:57
Не совсем по теме:
Я сделал, очень торопился, второй поток без использования backgroundWorker1. Есть переменная (глобальная) хранящая значение прогрессбара. Вот её-то я и инкрементирую в цикле второго потока. А кода включаю поток - включаю таймер обновления бара. Вот и все.
0
0 / 0 / 0
Регистрация: 13.01.2010
Сообщений: 35
09.01.2012, 23:13  [ТС]
а можно хотя б приблизительный код увидеть?

Добавлено через 17 минут
понимаю что это выглядит как-то так
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
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
using System;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Diagnostics;
 
namespace Program
{
    public partial class Form1 : Form
    {
        public int global1; // Используем для передачи одного из результатов фонового расчета в форму для отображения
 
        public Form1()
        {
            InitializeComponent();
            backgroundWorker1.DoWork += new DoWorkEventHandler(backgroundWorker1_DoWork); 
            backgroundWorker1.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backgroundWorker1_RunWorkerCompleted);
            backgroundWorker1.ProgressChanged += new ProgressChangedEventHandler(backgroundWorker1_ProgressChanged);
            backgroundWorker1.WorkerReportsProgress = true;
        }
 
        private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            toolStripProgressBar1.Value = e.ProgressPercentage; // Меняю данные прогрессбара
            toolStripStatusLabel1.Text = (String)e.UserState; // Меняю значение метки
        }
 
        // Расчет запускается при нажатии на кнопку button1
        private void button1_Click(object sender, EventArgs e)
        {
            button1.Enabled = false; // На время расчета блокируем опасные кнопки
            toolStrip1.Enabled = false;
 
            backgroundWorker1.RunWorkerAsync(); // ЗАПУСКАЕМ ВЫЧИСЛЕНИЯ В ФОНОВОМ ПОТОКЕ!!!!
        }
 
        // Точка запуска фоновых расчетов
        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            Calc(); // Вызываем метод с расчетами            
        }
 
        // Метод с расчетами
        private void Calc()
        {
            int bigNumber = 77777777;
            for (int i = 1; i < bigNumber; i++)
            {
                int n = (int)i * 100 / bigNumber; // вычисляем значение % для прогрессбара
                String s = "Выполнено " + n + "% расчета";
                backgroundWorker1.ReportProgress(n, s); // Отправляем данные в ProgressChanged
            }
            int global1 = i; // данные переменной global1 потом используем по окончании расчета для изменения формы 
            backgroundWorker1.ReportProgress(100, "Расчет завершен!"); // Выводим данные на форму
        }
        
        private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            button1.Enabled = true; // После окончания расчета разблокируем опасные кнопки
            toolStrip1.Enabled = true;
            label2.Text = "По окончанию расчета перешли к числу"  + global1;
            MessageBox.Show("Расчет окончен!");
        }
    }
}
но здесь опять же используется цикл для передачи данных в прогрессбар т.е. получается нсли я снасала пишу цикл и в нем передаю "процент" в прогрессбар, то он заполняется моментально, а расчет идет сам по себе, если расчет запускаю в цикле, то он считается лишнее кол-во раз, так где же прописать тогда вычисления, а где цикл для отображения процесса на прогрессбар?
0
 Аватар для Димон_
136 / 104 / 9
Регистрация: 30.01.2011
Сообщений: 699
09.01.2012, 23:14
Это в кнопке, запускающей действие
int progressBarValue =0;
объявлен в классе

C#
1
2
3
4
5
6
7
8
9
10
11
12
string name = lHandle[cbx_friendsBottom.SelectedIndex];
            this.progressBar1.Maximum = (int)numericUpDown2.Value*(int)numericUpDown3.Value - 1;
            int pause = (int)numericUpDown1.Value;
            int replay=(int) numericUpDown3.Value;
            int count =(int)numericUpDown2.Value;
            string text = textBox2.Text;
            progressBar1.Value = 0; 
            progressBarValue = 0;
            System.Threading.Thread t = new System.Threading.Thread(delegate() { ThreadOur(name, pause, replay, count, text); });
            t.IsBackground = true;
            t.Start();
            timer2.Enabled = true;
А вот в таймере:
C#
1
2
3
4
5
6
7
try { progressBar1.Value = progressBarValue; }
            catch 
            {
                progressBar1.Value = 0;
                progressBarValue=0;
                timer2.Enabled = false; 
            }
Добавлено через 1 минуту
Не смотри на то, как создан поток (это уже мое личное так сказать)
0
0 / 0 / 0
Регистрация: 13.01.2010
Сообщений: 35
09.01.2012, 23:57  [ТС]
что не очень понятно что происходит с progressBarValue как вижу что объявляется
Code
1
 progressBarValue=0;
а в таймере
Code
1
 progressBar1.Value = progressBarValue;
, но где же происходит тогда изменение самого progressBarValue?
0
Эксперт .NET
 Аватар для Casper-SC
4434 / 2094 / 404
Регистрация: 27.03.2010
Сообщений: 5,657
Записей в блоге: 1
10.01.2012, 01:51
Villiya, твой код по идее работать должен, а то начали уже изобретать что-то. Свойству WorkerReportsProgress присвой true.
0
0 / 0 / 0
Регистрация: 13.01.2010
Сообщений: 35
10.01.2012, 02:25  [ТС]
да, он работает, но работает сейчас очень медленно т.к. там в цикле 100 раз выполняется код
C#
1
2
3
CFirDoc p = new CFirDoc(id);               
                double TotalSeconds = p.Go();
                Form1.cdoc = p;
а если не в цикле его писать, то тогда прогрессбар работает сам по себе, а вычисления сами по себе, теперь дкмаю куда вставить эти 3 строчки чтоб они работали вместе и не 100 раз
0
Эксперт .NET
 Аватар для Casper-SC
4434 / 2094 / 404
Регистрация: 27.03.2010
Сообщений: 5,657
Записей в блоге: 1
10.01.2012, 03:08
Ну если бы знать что делает этот код, то можно было бы что-то придумать. И вообще нафиг нужен цикл? Используй свойства:
C#
1
2
            progressBar1.Style = ProgressBarStyle.Marquee;
            progressBar1.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 CalcBtn_Click(object sender, EventArgs e)
        {
            backgroundWorker1.RunWorkerAsync();
        }
       
        public void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
               //1 раз достаточно вызвать, знаю можно и по другому сделать,
               //но какая разница то? Пусть так будет
               backgroundWorker1.ReportProgress(0); 
               /////данный кусок должен остаться неизменным
                CFirDoc p = new CFirDoc(id);               
                double TotalSeconds = p.Go();
                Form1.cdoc = p;
        }
 
        private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            progressBar1.Style = ProgressBarStyle.Marquee;
        }
 
        public void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            progressBar1.Style = ProgressBarStyle.Blocks;
            MessageBox.Show("Работа завершена");
        }
1
 Аватар для Димон_
136 / 104 / 9
Регистрация: 30.01.2011
Сообщений: 699
10.01.2012, 10:24
инкрементируются в ThreadOur() этом методе..
0
Эксперт .NET
 Аватар для kolorotur
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
10.01.2012, 10:33
Цитата Сообщение от Villiya Посмотреть сообщение
C#
1
double TotalSeconds = p.Go();
В методе p.Go() наверное отдельный поток запускается, да?
0
0 / 0 / 0
Регистрация: 13.01.2010
Сообщений: 35
12.01.2012, 04:06  [ТС]
Цитата Сообщение от kolorotur Посмотреть сообщение
В методе p.Go() наверное отдельный поток запускается, да?
не совсем так, сам метод запускает просто вычисления - не поток, а вот этот метод уже необходимо запустить в новом потоке

Добавлено через 3 минуты
Цитата Сообщение от Casper-SC Посмотреть сообщение
И вообще нафиг нужен цикл?
в данном случае цикл использовался, по незнанию, только для отображения процесса в прогрессбаре, на самом деле он не несет никакой иной смысловой нагрузки
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
12.01.2012, 04:06
Помогаю со студенческими работами здесь

Заполнение ProgressBar посредством потока
Добрый вечер! Такое дело: я пишу программу по учёту документов, и в моей базе находятся около 24 тысяч этих самых документов. Для...

Шаг ProgressBar не из фонового потока
Можно ли каким-то образом сделать шаг в ProgressBar'e если он создан в фоновом потоке, а я хочу вызвать функцию шага в другом потоке, можно...

Изменить значение ProgressBar из потока
Доброго времени суток, форумчане. Необходима ваша помощь в правильной организации потоков. Есть основная форма, из которой создается...

Как двигать progressBar из другого потока?
когда вызываю LP_WI-&gt;ui.progressBar-&gt;setValue((i * 100)/ to); из потока, то вылетает ошибка, скрин ниже, как правльно делать?

Аварийное закрытие программы: ProgressBar с использованием дополнительного потока
В WPF набрал такой простенький пример с применением дополнительного потока: namespace TKControls { /// &lt;summary&gt; ///...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
17
Ответ Создать тему
Новые блоги и статьи
Установка Android SDK, NDK, JDK, CMake и т.д.
8Observer8 25.01.2026
Содержание блога Перейдите по ссылке: https:/ / developer. android. com/ studio и в самом низу страницы кликните по архиву "commandlinetools-win-xxxxxx_latest. zip" Извлеките архив и вы увидите. . .
Вывод текста со шрифтом TTF на Android с помощью библиотеки SDL3_ttf
8Observer8 25.01.2026
Содержание блога Если у вас не установлены Android SDK, NDK, JDK, и т. д. то сделайте это по следующей инструкции: Установка Android SDK, NDK, JDK, CMake и т. д. Сборка примера Скачайте. . .
Использование SDL3-callbacks вместо функции main() на Android, Desktop и WebAssembly
8Observer8 24.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
моя боль
iceja 24.01.2026
Выложила интерполяцию кубическими сплайнами www. iceja. net REST сервисы временно не работают, только через Web. Написала за 56 рабочих часов этот сайт с нуля. При помощи perplexity. ai PRO , при. . .
Модель сукцессии микоризы
anaschu 24.01.2026
Решили писать научную статью с неким РОманом
http://iceja.net/ математические сервисы
iceja 20.01.2026
Обновила свой сайт http:/ / iceja. net/ , приделала Fast Fourier Transform экстраполяцию сигналов. Однако предсказывает далеко не каждый сигнал (см ограничения http:/ / iceja. net/ fourier/ docs ). Также. . .
http://iceja.net/ сервер решения полиномов
iceja 18.01.2026
Выкатила http:/ / iceja. net/ сервер решения полиномов (находит действительные корни полиномов методом Штурма). На сайте документация по API, но скажу прямо VPS слабенький и 200 000 полиномов. . .
Расчёт переходных процессов в цепи постоянного тока
igorrr37 16.01.2026
/ * Дана цепь(не выше 3-го порядка) постоянного тока с элементами R, L, C, k(ключ), U, E, J. Программа находит переходные токи и напряжения на элементах схемы классическим методом(1 и 2 з-ны. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru