С Новым годом! Форум программистов, компьютерный форум, киберфорум
C# .NET
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.56/9: Рейтинг темы: голосов - 9, средняя оценка - 4.56
2 / 2 / 0
Регистрация: 16.02.2012
Сообщений: 12

Не могу достать данные из потока во время выполнения цикла

07.04.2012, 19:56. Показов 2074. Ответов 16
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Доброго времени суток.
Проблема вот в чём: есть код формы

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
 
private void button1_Click(object sender, EventArgs e)
        {
            
            var processor = new code();
            processor.Progress += ProcessorProgress;
 
            var thread = new Thread(processor.ThreadTask);
            thread.Start();
        
        }
        void ProcessorProgress(int progress)
        {
            if (progressBar1.InvokeRequired)
            {
                progressBar1.Invoke(new ProgressHandler(ProcessorProgress), progress);
            }
            else
            {
                progressBar1.Value = progress;
            }
        }
Он запускает процедуру в другом потоке

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
 namespace MyProject
{
    public delegate void ProgressHandler(int progress);
    public class code
 
    {
        public event ProgressHandler Progress;
        //бла-бла переменные
        public void ThreadTask()
        {
         //объявление экземпляров и т.д.
         using (StreamReader st = baseinfo.OpenText())
            {
                int i = 0;
                p = (int)baseinfo.Length;                  //Замеряю кол-во строк в файле
                while ((sText = st.ReadLine()) != null) //Построчно ввожу данные из файла
                {
                    
                    i++;                  //кол-во уже занесенных строк
                 
                    Progress((i / (p)) * 100); //высчитывание данных для ПрогрессБара(макс. знач. 100)
                }
            }
Суть в том, что ПрогрессБар заполняется уже после цикла и сразу встает на максимальное значение, далее по коду еще цикл for, там тоже самое. Как сделать, чтоб прогрессБар обновлялся во время циклов?

Заранее спасибо!
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
07.04.2012, 19:56
Ответы с готовыми решениями:

Выполнения цикла на заданное время
как сделать чтобы цикл while выполнялся определенное время?например,чтобы он выполнялся 3 секунды

Мьютексы-потоки: Как задать время выполнения потока
Подскажите пожалуйста насчет следующих вопросов, сам не разобрался. 1. Как задать время выполнения потока? 2. Как заставить потоки...

Перемещение формы во время выполнения цикла
Здравствуйте. Возникла проблема следующего характера. Во время выполнения какого нибудь долгого цикла, программа, своего рода, зависает, и...

16
Эксперт .NET
 Аватар для Casper-SC
4434 / 2094 / 404
Регистрация: 27.03.2010
Сообщений: 5,657
Записей в блоге: 1
07.04.2012, 20:04
Создай новый проект, воспроизведи в нём эту проблему (ну чтобы без лишнего ненужного кода) и скинь сюда, так будет намного легче тебе помочь. На первый взгляд пока не увидел в чём беда конкретно. Самому проект мутить относительно долго, а так скачал, затестил, попробовал как-то решить, если решил, то тут рассказал в чём проблема. Хотя может кто-то что-то посоветует и поможет без проекта, смотри сам.

Добавлено через 3 минуты
А, кстати, скорее всего просто цикл выполняется моментально, вот и не видно никакого продвижения...

Цитата Сообщение от aridscrut Посмотреть сообщение
Он запускает процедуру в другом потоке
Запускает
не важно, запускает/выполняет, сама суть что метод, а не процедура или функция. Так, чтобы знал.
метод.
0
2 / 2 / 0
Регистрация: 16.02.2012
Сообщений: 12
07.04.2012, 20:08  [ТС]
Ну смотрим, код формы:

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
        private void btnStart_Click(object sender, EventArgs e)
        {
            var processor = new FileProcessor();
            processor.Progress += ProcessorProgress;
 
            var thread = new Thread(processor.DoWork);
            thread.Start();
        }
        void ProcessorProgress(int progress)
        {
            if (progressBar1.InvokeRequired)
            {
                progressBar1.Invoke(new ProgressHandler(ProcessorProgress), progress);
            }
            else
            {
                progressBar1.Value = progress;
            }
        }
Код класса с вызываемой процедурой:

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
namespace Invoke
{
    public delegate void ProgressHandler(int progress);
 
    public class FileProcessor
    {
        public event ProgressHandler Progress;
 
        public void DoWork()
        {
            for (i = 1; i <= 100; i++)
            {
                Thread.Sleep(100);
                if (Progress != null) Progress(i);
                    
            }
        }
    }
}
И всё робит на УРА. В предыдущем же примере, при точно таком же синтаксисе ПрогрессБар упорно отказывается обновляться с положенным ему шагом
0
Эксперт .NET
 Аватар для Casper-SC
4434 / 2094 / 404
Регистрация: 27.03.2010
Сообщений: 5,657
Записей в блоге: 1
07.04.2012, 20:11
Цитата Сообщение от aridscrut Посмотреть сообщение
В предыдущем же примере, при точно таком же синтаксисе ПрогрессБар упорно отказывается обновляться с положенным ему шагом
А значения передаваемые на каждой итерации точно правильно просчитываются?

Добавлено через 1 минуту
Цитата Сообщение от aridscrut Посмотреть сообщение
C#
1
Progress((i / (p)) * 100); //высчитывание данных для ПрогрессБара(макс. знач. 100)
И вообще лучше вызывать обработчик события не каждую итерацию, а только когда значение процента изменяется, а то походу обращений к контролу просто огромное кол-во (ненужных нафиг).
0
2 / 2 / 0
Регистрация: 16.02.2012
Сообщений: 12
07.04.2012, 20:13  [ТС]
Расчитываются правильно, я их и в int конвертировал спецом уже. И цикл этот довольно долгий, файлы по 2-3 метра

Добавлено через 1 минуту
Цитата Сообщение от Casper-SC Посмотреть сообщение
И вообще лучше вызывать обработчик события не каждую итерацию, а только когда значение процента изменяется, а то походу обращений к контролу просто огромное кол-во (ненужных нафиг).
Да это-то бог с ним, это не проблема, основная проблема у меня описана в топе
0
Эксперт .NET
 Аватар для Casper-SC
4434 / 2094 / 404
Регистрация: 27.03.2010
Сообщений: 5,657
Записей в блоге: 1
07.04.2012, 20:15
Цитата Сообщение от aridscrut Посмотреть сообщение
Да это-то бог с ним, это не проблема, основная проблема у меня описана в топе
А вдруг проблема в этом и есть? Была тут какая-то тема, что тормозил интерфейс из-за вот таких же миллионов обращений к прогрес бару. Проверь, возможно в этом и есть проблема.
0
2 / 2 / 0
Регистрация: 16.02.2012
Сообщений: 12
07.04.2012, 20:17  [ТС]
Цитата Сообщение от Casper-SC Посмотреть сообщение
А вдруг проблема в этом и есть? Была тут какая-то тема, что тормозил интерфейс из-за вот таких же миллионов обращений к прогрес бару. Проверь, возможно в этом и есть проблема.
Интерфейс тормозить не может, так как все расчеты у меня запущены в другом потоке

Добавлено через 1 минуту
Если б тормозил интерфейс, то форма бы не отвечала, а она держится молодцом=)
0
Эксперт .NET
 Аватар для Casper-SC
4434 / 2094 / 404
Регистрация: 27.03.2010
Сообщений: 5,657
Записей в блоге: 1
07.04.2012, 20:30
Что-то там не правильно считается. Точка останова срабатывает 1 раз и значение t == 100
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
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            Shown += new EventHandler(Form1_Shown);
        }
 
        void Form1_Shown(object sender, EventArgs e)
        {
            OperationStart();
        }
 
        private void OperationStart()
        {
            var processor = new FileProcessor();
            processor.Progress += ProcessorProgress;
 
            var thread = new Thread(processor.DoWork);
            thread.Start();
        }
 
        void ProcessorProgress(int progress)
        {
            if (progressBar1.InvokeRequired)
                progressBar1.Invoke((ProgressHandler)ProcessorProgress, progress);
            else
                progressBar1.Value = progress;
        }
    }
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
    public delegate void ProgressHandler(int progress);
 
    public class FileProcessor
    {
        public event ProgressHandler Progress;
 
        public void DoWork()
        {
            const int IterationsQuantity = 100000;
            for (int i = 1; i <= IterationsQuantity; i++)
            {
                int t = (i / (IterationsQuantity)) * 100;
                if (t > 1)
                { //Тут поставь точку останова
                }
                Progress(t); 
            }
        }
    }
Добавлено через 4 минуты
И ещё, если не вызывать метод Progress каждую итерацию, то цикл выполняется моментально, если вызывать, то можно уснуть пока он закончит своё выполнение.

Добавлено через 51 секунду
Вот сравни и глянь на увеличенное кол-во итераций:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
    public delegate void ProgressHandler(int progress);
 
    public class FileProcessor
    {
        public event ProgressHandler Progress;
 
        public void DoWork()
        {
            const int IterationsQuantity = 10000000;
            int prevPercent = 0;
 
            for (int i = 1; i <= IterationsQuantity; i++)
            {
                int currentPercentage = (i / (IterationsQuantity)) * 100;
                if (prevPercent != currentPercentage)
                {
                    Progress(currentPercentage);
                    prevPercent = currentPercentage;
                }
            }
        }
    }
0
2 / 2 / 0
Регистрация: 16.02.2012
Сообщений: 12
07.04.2012, 20:34  [ТС]
Этот код и так пашет норм. Или ты хочешь, чтоб я сравнил рабочий и нерабочий примеры?
0
Эксперт .NET
 Аватар для Casper-SC
4434 / 2094 / 404
Регистрация: 27.03.2010
Сообщений: 5,657
Записей в блоге: 1
07.04.2012, 20:36
Вот держи:
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
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            Shown += new EventHandler(Form1_Shown);
        }
 
        void Form1_Shown(object sender, EventArgs e)
        {
            OperationStart();
        }
 
        private void OperationStart()
        {
            var processor = new FileProcessor();
            processor.Progress += ProcessorProgress;
 
            var thread = new Thread(processor.DoWork);
            thread.Start();
        }
 
        void ProcessorProgress(int progress)
        {
            if (progressBar1.InvokeRequired)
                progressBar1.Invoke((ProgressHandler)ProcessorProgress, progress);
            else
                progressBar1.Value = progress;
        }
    }
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
    public delegate void ProgressHandler(int progress);
 
    public class FileProcessor
    {
        public event ProgressHandler Progress;
 
        public void DoWork()
        {
            const float IterationsQuantity = 1000000000F;
            int prevPercent = 0;
 
            for (int i = 1; i <= IterationsQuantity; i++)
            {
                double d = i / IterationsQuantity;
                int currentPercentage = (int)((i / IterationsQuantity) * 100);
                if (prevPercent != currentPercentage)
                {
                    Progress(currentPercentage);
                    prevPercent = currentPercentage;
                }
            }
        }
    }
Добавлено через 2 минуты
Цитата Сообщение от aridscrut Посмотреть сообщение
Этот код и так пашет норм.
Незнаю что там сравниваешь, но вызывать метод Progress каждую итерацию, это просто говнокод (который ещё и замедляет скорость работы всего цикла).
1
2 / 2 / 0
Регистрация: 16.02.2012
Сообщений: 12
07.04.2012, 20:39  [ТС]
Я имею ввиду, что ты перепутал коды! Ты показываешь на примере, где всё работает как надо

Добавлено через 34 секунды
В общем, суть ясна, ща я перекурю, всё опробую и отпишусь
0
Эксперт .NET
 Аватар для Casper-SC
4434 / 2094 / 404
Регистрация: 27.03.2010
Сообщений: 5,657
Записей в блоге: 1
07.04.2012, 20:41
Цитата Сообщение от aridscrut Посмотреть сообщение
Я имею ввиду, что ты перепутал коды! Ты показываешь на примере, где всё работает как надо
Не работает там как надо, если считать проценты так как ты считал. А если считать так как я считаю в последнем примере, то всё работает. Тебе нужно просто считать также как у меня считается процент и инициировать событие Progress, только при изменении процента, иначе искуственно значительно увеличиваешь время выполнения кода в цикле.

Блин, не понимаю, почему никто не слушает что им говоришь, ладно я бы это сам придумал, ведь дело говорю.
0
2 / 2 / 0
Регистрация: 16.02.2012
Сообщений: 12
07.04.2012, 21:07  [ТС]
Ну что ж, проблема не решена!

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
                p = (int)baseinfo.Length;
                while ((sText = st.ReadLine()) != null)
                {
                    
                    
                    i++;
                    int currentPercentage = (int)((i / p) * 100);
                  
                   
                    if (prevPercent != currentPercentage)
                    {
                        Progress(currentPercentage);
                        prevPercent = currentPercentage;
                        
                    }
                }
Теперь прогрессБар отказывается вообще подавать признаки жизни. Т.е. даже после выполнения цикла не показывает сразу полную загрузку
0
Эксперт .NET
 Аватар для Casper-SC
4434 / 2094 / 404
Регистрация: 27.03.2010
Сообщений: 5,657
Записей в блоге: 1
07.04.2012, 21:11
Цитата Сообщение от aridscrut Посмотреть сообщение
Ну что ж, проблема не решена!
Проблема помоему как раз решена. Читать внимательнее надо.
C#
1
2
3
            const float IterationsQuantity = 1000000000F;
            //-------------
                int currentPercentage = (int)((i / IterationsQuantity) * 100);
Вроде так:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
                p = (float)baseinfo.Length; //приводим к типу float
                while ((sText = st.ReadLine()) != null)
                {
                    i++;
                    int currentPercentage = (int)((i / p) * 100);
 
                    if (prevPercent != currentPercentage)
                    {
                        Progress(currentPercentage);
                        prevPercent = currentPercentage;
                        
                    }
                }
1
2 / 2 / 0
Регистрация: 16.02.2012
Сообщений: 12
07.04.2012, 21:11  [ТС]
на этом примере всё работает отлично

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
 public void DoWork()
        {
            const float IterationsQuantity = 1000000000F;
            int prevPercent = 0;
 
            for (int i = 1; i <= IterationsQuantity; i++)
            {
               
                int currentPercentage = (int)((i / IterationsQuantity) * 100);
                if (prevPercent != currentPercentage)
                {
                    Progress(currentPercentage);
                    prevPercent = currentPercentage;
                }
            }
        }
0
Эксперт .NET
 Аватар для Casper-SC
4434 / 2094 / 404
Регистрация: 27.03.2010
Сообщений: 5,657
Записей в блоге: 1
07.04.2012, 21:14
Я выше показал решение, может ты просто не заметил...

Добавлено через 57 секунд
Просто, если делишь целое на целое, то и получаешь целое, а если на вещественное, то получаешь тоже вещественное.
1
2 / 2 / 0
Регистрация: 16.02.2012
Сообщений: 12
07.04.2012, 21:18  [ТС]
Хм... да с float'ом всё начало шуршать потихоньку, только не совсем так как надо, он после 1 шага дальше не движется, ну с этим разберемся. А почему с int не работало?

Добавлено через 2 минуты
Всё, спасибо большое. Общий смысл ясен. Пошел далее работать=)
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
07.04.2012, 21:18
Помогаю со студенческими работами здесь

Окно программы во время выполнения цикла
Пока выполняется цикл в программе окно становится не доступным. Ни свернуть не переместить и тд. Как с этим бороться? Цикл запускается...

Как задать время выполнения цикла в секундах?
Здравствуйте. кусок кода для вывода строки текста на экран const char string1 = &quot;sample of text&quot;; HDC dc =...

Как закрыть программу во время выполнения цикла while
У меня возникла такая проблема, когда я пытаюсь закрыть программу во время выполнения while у меня она тупо не закрывается, хотелось-бы...

Не могу достать нужные данные из Json
Всем доброго времени суток) Помогите пожалуйста вывести нужные данные из Json. Мой код: using System; using...

SIMATIC S7-400. Почему увеличивается время выполнения программного цикла?
Как узнать, почему увеличивается время выполнения программного цикла?


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

Или воспользуйтесь поиском по форуму:
17
Ответ Создать тему
Новые блоги и статьи
Учёным и волонтёрам проекта «Einstein@home» удалось обнаружить четыре гамма-лучевых пульсара в джете Млечного Пути
Programma_Boinc 01.01.2026
Учёным и волонтёрам проекта «Einstein@home» удалось обнаружить четыре гамма-лучевых пульсара в джете Млечного Пути Сочетание глобально распределённой вычислительной мощности и инновационных. . .
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост.
Programma_Boinc 28.12.2025
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост. Налог на собак: https:/ / **********/ gallery/ V06K53e Финансовый отчет в Excel: https:/ / **********/ gallery/ bKBkQFf Пост отсюда. . .
Кто-нибудь знает, где можно бесплатно получить настольный компьютер или ноутбук? США.
Programma_Boinc 26.12.2025
Нашел на реддите интересную статью под названием Anyone know where to get a free Desktop or Laptop? Ниже её машинный перевод. После долгих разбирательств я наконец-то вернула себе. . .
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка.
Programma_Boinc 23.12.2025
Рецензия / Мнение/ Перевод Нашел на реддите интересную статью под названием The Thinkpad X220 Tablet is the best budget school laptop period . Ниже её машинный перевод. Thinkpad X220 Tablet —. . .
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru