С Новым годом! Форум программистов, компьютерный форум, киберфорум
C# Windows Forms
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.89/9: Рейтинг темы: голосов - 9, средняя оценка - 4.89
 Аватар для KorPaEv
58 / 34 / 8
Регистрация: 08.07.2011
Сообщений: 235

Thread.Sleep совместно с BeginInvoke

01.08.2017, 11:20. Показов 1963. Ответов 9
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Приветствую уважаемые!

Вопрос следующий: имеем данные которые заполняются в потоке, заполнение DataGridView через делегата, чтобы корректно обновлять данные на форме, собственно при этом никаким образом выполнение потока не продолжается, хотя после BeginInvoke пишу Thread.Sleep(1000) как пример.

Собственно отрабатывает все, кроме продолжения выполнения потока с периодичностью раз в секунду или не важно.

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
using System;
using System.Data;
using System.Diagnostics;
using System.Threading;
using System.Windows.Forms;
 
namespace ProcessesList
{
    public partial class MainForm : Form
    {
        Thread thread;
        private delegate void FillGridDelegate(); // делегат для функции
        DataTable table;
 
        public MainForm()
        {
            InitializeComponent();
            thread = new Thread(OnRefreshGrid); //Вызываем функу в потоке
            thread.Start(); //СТАРТУЕМ ПОТОК
        }
    
        void OnRefreshGrid()
        {
            FillGridDelegate FillD = new FillGridDelegate(FillGrid); // создаем делегат с указателем на нужную функцию
            if (this.InvokeRequired)
            {
                this.BeginInvoke(FillD); // выполняем ее в том потоке где был создан элемент 
                Thread.Sleep(1000); //Продолжим выполнение потока через секунду
            }
        }
 
        private void FillGrid()
        {
            BindingSource source = new BindingSource();
            table = new DataTable("Process List");
 
            Process[] processes = Process.GetProcesses();
 
            table.Columns.Add("ProcessName");
            table.Columns.Add("ProcessId");
 
            for (int i = 0; i < processes.Length; ++i)
            {
                table.Rows.Add(new object[] { processes[i].ProcessName + ".exe", processes[i].Id });
                Application.DoEvents(); // Чтобы программа не висела пока идет заполнение 
            }
 
            table.AcceptChanges();
            source.DataSource = table;
 
            int scroll = dataGridView1.FirstDisplayedScrollingRowIndex;
            dataGridView1.DataSource = source;
 
            if (scroll != -1)
                dataGridView1.FirstDisplayedScrollingRowIndex = scroll;
        }
    }
}
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
01.08.2017, 11:20
Ответы с готовыми решениями:

ProgressBar и Thread.Sleep
Задание: 1 . Создание Windows приложения, которое демонстрирует асинхронную работу в фоновом режиме. Написать метод , выполнение...

Не работает Thread.Sleep();
Не работает задержка. Вернее она работает, но сначала программа делает задержку, а затем отображает текст. if (Data.pin == pin_vvod) ...

Странное поведение Thread.Sleep
Эх, прошу помочь. В общем. Есть поток выполняющий эту функцию: { Begin: CoreInProcessing = true; for...

9
Администратор
Эксперт .NET
 Аватар для OwenGlendower
18245 / 14169 / 5366
Регистрация: 17.03.2014
Сообщений: 28,849
Записей в блоге: 1
01.08.2017, 12:17
KorPaEv, метод OnRefreshGrid продолжает выполнение после Thread.Sleep и завершается. Что означает завершение потока. Так что код работает верно. Кстати такая схема работы - поток который только делает Invoke - не несет никакой пользы потому что вся работа все равно делается в UI потоке.
0
 Аватар для KorPaEv
58 / 34 / 8
Регистрация: 08.07.2011
Сообщений: 235
01.08.2017, 12:27  [ТС]
Цитата Сообщение от OwenGlendower Посмотреть сообщение
KorPaEv, метод OnRefreshGrid продолжает выполнение после Thread.Sleep и завершается. Что означает завершение потока. Так что код работает верно. Кстати такая схема работы - поток который только делает Invoke - не несет никакой пользы потому что вся работа все равно делается в UI потоке.
В том то и дело что у меня не продолжается выполнение OnRefreshGrid после Thread.Sleep. У меня вызов метода происходит всего один раз и грид не обновляет информацию о процессах в текущий момент. Почему выполнение не циклится?
Где можно почитать как правильно обновлять данные грида в потоке с какой то периодичностью по времени?

Добавлено через 1 минуту
Цитата Сообщение от OwenGlendower Посмотреть сообщение
Кстати такая схема работы - поток который только делает Invoke - не несет никакой пользы потому что вся работа все равно делается в UI потоке.
+ как раз и была задумка выполнять обновление грида в отдельном потоке отличным от UI в отдельном классе, просто еще не вынес в отдельный класс
0
Администратор
Эксперт .NET
 Аватар для OwenGlendower
18245 / 14169 / 5366
Регистрация: 17.03.2014
Сообщений: 28,849
Записей в блоге: 1
01.08.2017, 12:37
Цитата Сообщение от KorPaEv Посмотреть сообщение
Почему выполнение не циклится?
С какой стати оно должно циклится если в коде нет цикла? Thread.Sleep это только пауза, а не какой-то магический способ периодического выполнения кода.

Цитата Сообщение от KorPaEv Посмотреть сообщение
Где можно почитать как правильно обновлять данные грида в потоке с какой то периодичностью по времени?
Используй класс Timer.
1
 Аватар для KorPaEv
58 / 34 / 8
Регистрация: 08.07.2011
Сообщений: 235
01.08.2017, 14:54  [ТС]
Цитата Сообщение от OwenGlendower Посмотреть сообщение
Используй класс Timer.
Сделал вот так, все работает, но есть несколько проблем
1 - Каким образом сохранять возможность использовать скролл в гриде не зависимо от обновления грида?
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
using System;
using System.Windows.Forms;
 
namespace ProcessesList
{
    public partial class MainForm : Form
    {
        String processId;
        MyThread myThread;
        Timer timer;
 
        public MainForm()
        {
            InitializeComponent();
 
            timer = new Timer();
            timer.Interval = 500;
            timer.Tick += new EventHandler(timerTick);
            timer.Start();
            
        }
 
        private void timerTick(object sender, EventArgs e)
        {
            myThread = new MyThread(dataGridView1);
        }
    }
}
Класс обработчик данных

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
using System.Data;
using System.Diagnostics;
using System.Threading;
using System.Windows.Forms;
 
namespace ProcessesList
{
    class MyThread
    {
        Thread thread;
        DataTable table;
        DataGridView dataGridView;
        
        public MyThread(DataGridView dgv)
        {
            dataGridView = dgv;
            thread = new Thread(OnRefreshGrid);
            thread.Start();
        }
 
        void OnRefreshGrid()
        {
            FillGrid();
        }
 
        private void FillGrid()
        {
            table = new DataTable("Process List");
 
            Process[] processes = Process.GetProcesses();
 
            table.Columns.Add("ProcessName");
            table.Columns.Add("ProcessId");
 
            for (int i = 0; i < processes.Length; ++i)
            {
                table.Rows.Add(new object[] { processes[i].ProcessName + ".exe", processes[i].Id });
                Application.DoEvents(); 
            }
 
            table.AcceptChanges();
 
            dataGridView.Invoke((MethodInvoker)delegate
            {
                dataGridView.DataSource = null;
                dataGridView.DataSource = table;
            });
 
            int scroll = dataGridView.FirstDisplayedScrollingRowIndex;
 
            if (scroll != -1)
                dataGridView.FirstDisplayedScrollingRowIndex = scroll;
        }
    }
}
0
360 / 287 / 76
Регистрация: 21.06.2016
Сообщений: 1,115
01.08.2017, 16:06
KorPaEv, у Вас огромная архитектурная ошибка. Вы пытаетесь в том же методе, что и считает - сразу же обновить контрол. Разделяй и властвуй наше всё. Выносите в отдельный поток расчет отдельной таблицы, которая никак не связана с гридом, а потом просто подмените одну на вторую в UI потоке, и грид сам поменяется, это мгновенная операция, а у Вас всё слишком мудрёно получилось.
1
Эксперт .NET
 Аватар для Rius
13050 / 7616 / 1664
Регистрация: 25.05.2015
Сообщений: 23,160
Записей в блоге: 14
01.08.2017, 16:28
KorPaEv, от того, что вы запустили поток, потом из потока запустили синхронно с UI обновление грида, это обновление не будет магическим образом выполняться в потоке, а будет вешать UI программы.

DoEvents - признак говнокода.
1
 Аватар для KorPaEv
58 / 34 / 8
Регистрация: 08.07.2011
Сообщений: 235
02.08.2017, 05:58  [ТС]
Цитата Сообщение от hoolygan Посмотреть сообщение
Выносите в отдельный поток расчет отдельной таблицы, которая никак не связана с гридом, а потом просто подмените одну на вторую в UI потоке, и грид сам поменяется, это мгновенная операция
Вот так получается класс который будет обрабатывать отдельную табличку

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
using System.Data;
using System.Diagnostics;
using System.Threading;
 
namespace ProcessesList
{
    class MyThread
    {
        public DataTable table;
        Thread thread;
 
        public MyThread()
        {
            thread = new Thread(FillTable);
            thread.Start();
        }
 
        private void FillTable(object state)
        {
            table = new DataTable("Process List");
 
            Process[] processes = Process.GetProcesses();
 
            table.Columns.Add("ProcessName");
            table.Columns.Add("ProcessId");
 
            for (int i = 0; i < processes.Length; ++i)
            {
                table.Rows.Add(new object[] { processes[i].ProcessName + ".exe", processes[i].Id });
            }
        }
    }
}
А вот теперь каким образом передать в основной поток UI заполненную табличку?

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
using System;
using System.Data;
using System.Threading;
using System.Windows.Forms;
 
namespace ProcessesList
{
    public partial class MainForm : Form
    {
        MyThread myThread;
        System.Threading.Timer timer;
        DataTable table;
 
        public MainForm()
        {
            InitializeComponent();
            timer = new System.Threading.Timer(new TimerCallback(DoSomething), null, 0, 1000);           
        }
 
        private void DoSomething(object obj)
        {
            myThread = new MyThread();
        }
    }
}
0
Эксперт .NET
 Аватар для Rius
13050 / 7616 / 1664
Регистрация: 25.05.2015
Сообщений: 23,160
Записей в блоге: 14
02.08.2017, 06:19
Цитата Сообщение от KorPaEv Посмотреть сообщение
А вот теперь каким образом передать в основной поток UI заполненную табличку?
Оформить подключение DataTable к DataGridView в делегат и вызвать его через BeginInvoke.
А перед запуском потока отключать DataTable от DataGridView.
1
360 / 287 / 76
Регистрация: 21.06.2016
Сообщений: 1,115
02.08.2017, 06:46
А я бы не морочился со thread-ами, а оформил бы таску, которая вернет табличку.
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
02.08.2017, 06:46
Помогаю со студенческими работами здесь

Как остановить thread.Sleep по клику
дело такое - опрашиваю ком порты. есть функция и класс, отвечающие за разные методы. приходится ставить thread.sleep() чтобы получить...

Thread.Sleep только для одной формы
Здравствуйте столкнулся с такой штукой, есть form1 на ней кнопка, в которой создается и открывается form2, на form2 кнопка которая делает...

Thread.Sleep(): не видны визуальные изменения на форме между слипами
Проблема: не вижу смену цвета ячеек, а по логике должны меняться каждые 5 секунд(столько выполняется, или вернее спит, метод, а потом...

System.Threading.Thread.Sleep запускается не там, где прописан
Здравствуйте! У меня есть форма, на ней различные &quot;label&quot;, из которых состоит уровень, а есть &quot;label&quot; во всю программу, на...

Thread.Sleep в главном потоке или как сделать нормальную задержку
Здравствуйте, мне нужно сделать задержку, хотелось бы через Thread.Sleep, но использование его в UI-потоке, как известно, приводит к...


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

Или воспользуйтесь поиском по форуму:
10
Ответ Создать тему
Новые блоги и статьи
Модель микоризы: классовый агентный подход
anaschu 02.01.2026
Раньше это было два гриба и бактерия. Теперь три гриба, растение. И на уровне агентов добавится между грибами или бактериями взаимодействий. До того я пробовал подход через многомерные массивы,. . .
Учёным и волонтёрам проекта «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-динозавры, а новое поколение лёгких потоков. Откат?. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru