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

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

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

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

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
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
07.04.2012, 19:56
Ответы с готовыми решениями:

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

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

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

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

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

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

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

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
4432 / 2092 / 404
Регистрация: 27.03.2010
Сообщений: 5,657
Записей в блоге: 1
07.04.2012, 20:11 4
Цитата Сообщение от aridscrut Посмотреть сообщение
В предыдущем же примере, при точно таком же синтаксисе ПрогрессБар упорно отказывается обновляться с положенным ему шагом
А значения передаваемые на каждой итерации точно правильно просчитываются?

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

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

Добавлено через 1 минуту
Если б тормозил интерфейс, то форма бы не отвечала, а она держится молодцом=)
0
Эксперт .NET
4432 / 2092 / 404
Регистрация: 27.03.2010
Сообщений: 5,657
Записей в блоге: 1
07.04.2012, 20:30 8
Что-то там не правильно считается. Точка останова срабатывает 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  [ТС] 9
Этот код и так пашет норм. Или ты хочешь, чтоб я сравнил рабочий и нерабочий примеры?
0
Эксперт .NET
4432 / 2092 / 404
Регистрация: 27.03.2010
Сообщений: 5,657
Записей в блоге: 1
07.04.2012, 20:36 10
Вот держи:
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  [ТС] 11
Я имею ввиду, что ты перепутал коды! Ты показываешь на примере, где всё работает как надо

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

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

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
4432 / 2092 / 404
Регистрация: 27.03.2010
Сообщений: 5,657
Записей в блоге: 1
07.04.2012, 21:11 14
Цитата Сообщение от 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  [ТС] 15
на этом примере всё работает отлично

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
4432 / 2092 / 404
Регистрация: 27.03.2010
Сообщений: 5,657
Записей в блоге: 1
07.04.2012, 21:14 16
Я выше показал решение, может ты просто не заметил...

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

Добавлено через 2 минуты
Всё, спасибо большое. Общий смысл ясен. Пошел далее работать=)
0
07.04.2012, 21:18
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
07.04.2012, 21:18
Помогаю со студенческими работами здесь

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

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

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

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


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

Или воспользуйтесь поиском по форуму:
17
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru