Форум программистов, компьютерный форум, киберфорум
C# для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 5.00/6: Рейтинг темы: голосов - 6, средняя оценка - 5.00
4 / 4 / 4
Регистрация: 29.11.2014
Сообщений: 131

Работа с потоками

22.11.2016, 21:24. Показов 1199. Ответов 6
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Объясните мне мои ошибки и как их поправить(грузит ЦП и делает невозможным работу с GUI программы - лагает ужасно)
Есть некий класс, в котором происходит работа с потоками - выдержку я представлю ниже. Запускается он из основного потока, вызовом метода CreateThread.
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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
        private Thread[] Threads;
        public void CreateThread()
        {
            try
            {
                Threads = new Thread[101];
                for (int i = 0; i < 100; i++)
                {
                    Threads[i] = new Thread(this.Worker);
                    Threads[i].IsBackground = true;
                    Threads[i].Start();
                }
 
            }
            catch (Exception)
            {
            }
        }
 
        public void StopThreads()
        {
            try
            {
                for (int i = 0; i < 100; i++)
                {
                    Threads[i].Abort();
                }
            }
            catch (Exception)
            {
            }
        }
 
        public int AliveThreads()
        {
            try
            {
                int count = 0;
                for (int i = 0; i < 100; i++)
                {
                    if (Threads[i].IsAlive)
                    {
                        count++;
                    }
                }
                return count;
            }
            catch
            {
                return 0;
            }
 
        }
 
        void Worker()
        {
            while (SomeQueue1.Count != 0)
            {
                
                if (SomeQueue1.Count + 1 < AliveThreads() && SomeQueue2.Count+1 < AliveThreads())
                {
                    break;
                }
                string data = SomeQueue1.Dequeue();
                try
                {
                    Check(data);
                }
                catch (Exception)
                {
                  SomeQueue.Enqueue(data);
                }
                if (SomeQueue2.Count != 0)
                {
                    string datae = SomeQueue2.Dequeue();
                    try
                    {
                            Check2(datae);
                    }
                    catch (Exception)
                    {
                        SomeQueue2.Enqueue(datae);
                    }
                }
            }
Возможно, моя ошибка в методе обновления GUI. Как вы понимаете,после выполнения Check и Check2 появляются какие-то новые данные, которые я вношу в GUI через таймер, который запускается в самом начале с интервалом в 1000 мс(не из потока же его обноволять, ну). Но что-то я сомневаюсь, что моя проблема в таймере. Скорее всего, я просто неправильно работаю с потоками.
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
22.11.2016, 21:24
Ответы с готовыми решениями:

Работа с потоками
В буфере имеется N записей типа Type. К этим записям на чтение и на запись обращаются m потоков. Каждый из потоков может изменить...

Работа с потоками!
Ребята, никогда раньше с потоками не работал... Вот помогите решить проблему Есть метод DrawClicked(bubbleSort, (Button)sender,...

Работа с потоками
Помогите начинающему программисту!!! Нужно написать программу в которой есть два дочерних потока. В главном потоке интовой переменной...

6
907 / 664 / 318
Регистрация: 23.10.2016
Сообщений: 1,543
22.11.2016, 21:50
Этот код содержит ошибки. Одна из них:
C#
1
2
3
4
                if (SomeQueue2.Count != 0)
                {
                    // здесь нет никаких гарантий, что SomeQueue2 содержит хоть 1 элемент
                    string datae = SomeQueue2.Dequeue();
Насчёт лагов. Они могут быть из-за того, что процессор полностью загружен работой.
0
Злой няш
 Аватар для I2um1
2136 / 1505 / 565
Регистрация: 05.04.2010
Сообщений: 2,881
22.11.2016, 21:56
Цитата Сообщение от allCrowley Посмотреть сообщение
моя ошибка
1. Создаешь 101 поток, но используешь 100. И вообще так много потоков создавать неэффективно. Использовать Thread тоже не эффективно.
2. Производительность просаживается скорее всего из-за try-catch. Писать пустой catch - очень плохая практика.
3. GUI надо обновлять не через таймер, а через методы диспетчера Invoke/BeginInvoke.
4. Потоки работают с общими ресурсами: SomeQueue и SomeQueue2. Необходимо использовать синхронизацию потоков.

Добавлено через 3 минуты
Критической секции для синхронизации потоков должно хватить: используй Monitor, а потом почитай про “стройную” синхронизацию.
1
4 / 4 / 4
Регистрация: 29.11.2014
Сообщений: 131
22.11.2016, 22:41  [ТС]
Цитата Сообщение от I2um1 Посмотреть сообщение
Использовать Thread тоже не эффективно.
Если использовать Thread неэффективно, то как еще мне за 5 секунд отправить в сеть 100 запросов и обработать их?
Цитата Сообщение от I2um1 Посмотреть сообщение
2. Производительность просаживается скорее всего из-за try-catch. Писать пустой catch - очень плохая практика.
В некоторых участках кода мне нужно, чтобы ошибки(которые приводят к завершению работы программы) не возникали(иногда они возникают рандомно - на одной и той же операции, с одними и теми же входными данными). Сделать это проще, чем через конструкцию try catch где catch пустой - я не знаю.
Цитата Сообщение от I2um1 Посмотреть сообщение
GUI надо обновлять не через таймер, а через методы диспетчера Invoke/BeginInvoke.
Поправлю, спасибо!
Цитата Сообщение от I2um1 Посмотреть сообщение
Потоки работают с общими ресурсами: SomeQueue и SomeQueue2. Необходимо использовать синхронизацию потоков.
Для чего? Как я понимаю, синхронизировать потоки нужно чтобы не возникало путаницы. Но ее и так не возникает - единственная проблема, это лагающий интерфейс даже на 3-4 потоках.

Добавлено через 3 минуты
Цитата Сообщение от TopLayer Посмотреть сообщение
C#
1
2
3
4
if (SomeQueue2.Count != 0)
* * * * * * * * {
* * * * * * * * * * // здесь нет никаких гарантий, что SomeQueue2 содержит хоть 1 элемент
* * * * * * * * * * string datae = SomeQueue2.Dequeue();
Почему гарантий нету? Я же условием проверил - если очередь не пустая, то следующий элемент очереди помещаем в datae.
0
Злой няш
 Аватар для I2um1
2136 / 1505 / 565
Регистрация: 05.04.2010
Сообщений: 2,881
22.11.2016, 22:54
Цитата Сообщение от allCrowley Посмотреть сообщение
Если использовать Thread неэффективно, то как еще мне за 5 секунд отправить в сеть 100 запросов и обработать их?
Потоков лучше создавать столько, сколько на компьютере существует физических потоков у процессора. Вместо Thread лучше использовать Task.

Цитата Сообщение от allCrowley Посмотреть сообщение
в сеть 100 запросов
Дефолтное количество соединений 2 (ДВА). Здесь есть кое-какое объяснение https://blogs.msdn.microsoft.c... tionlimit/

Цитата Сообщение от allCrowley Посмотреть сообщение
иногда они возникают рандомно
Они возникают из-за одновременного доступа к общим ресурсам: SomeQueue и SomeQueue2. Эти операции надо синхронизировать с помощью объектов синхронизации.

Цитата Сообщение от allCrowley Посмотреть сообщение
Почему гарантий нету? Я же условием проверил - если очередь не пустая
Допустим первый поток проверяет условие:
C#
1
if (SomeQueue2.Count != 0)
И оно выполняется - в очереди к примеру один элемент.
Далее второй поток выполняет:
C#
1
string datae = SomeQueue2.Dequeue();
Тем самым, когда первый поток дойдет до операции:
C#
1
string datae = SomeQueue2.Dequeue();
И выполнит ее, то произойдет исключение, из-за которого очень сильно падает производительность.
1
4 / 4 / 4
Регистрация: 29.11.2014
Сообщений: 131
23.11.2016, 02:00  [ТС]
Цитата Сообщение от I2um1 Посмотреть сообщение
И выполнит ее, то произойдет исключение, из-за которого очень сильно падает производительность.
Понял, спасибо!
0
 Аватар для Sanya_sa
912 / 816 / 333
Регистрация: 03.02.2015
Сообщений: 5,276
Записей в блоге: 9
23.11.2016, 03:27
Цитата Сообщение от allCrowley Посмотреть сообщение
Если использовать Thread неэффективно, то как еще мне за 5 секунд отправить в сеть 100 запросов и обработать их?
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
private object ObjLock = new object();
 
void SendMsg(object data)
{
  lock(ObjLock)
  {
      // Тут код отправки сообщения
   }
}
 
 
void Send (datas)
{
    foreach(it in datas)
    {
       ThreadPool.QueueUserWorkItem(SendMsg, (object)it.dataSend);
    }
}
datas- массив из обьектов(data) необходимого для отправки сообщения.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
23.11.2016, 03:27
Помогаю со студенческими работами здесь

Работа с потоками
Всем привет, прошу подсказать есть программка рисующая спираль Архимеда так вот нужно распределить потоки между дугами фигуры (один поток -...

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

Работа с потоками
Возникли трудности с потоками. Необходимо, чтобы один поток считывал с консоли, другой выводил эту же информацию на консоль. Поток, который...

Работа с потоками
В общем, сделал рекурсивное удаление файлов и папок в несколько потоков, но вылетают эксепшены что файл уже удален. Можно ли как-то...

Работа с потоками
Добрые люди дайте готовый кусочек кода по работе с потоками Требования такие Запустив энное количество потоков мне надо дождаться их...


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

Или воспользуйтесь поиском по форуму:
7
Ответ Создать тему
Новые блоги и статьи
[Owen Logic] Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора
ФедосеевПавел 14.03.2026
Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора ВВЕДЕНИЕ Выполняя задание на управление насосной группой заполнения резервуара,. . .
делаю науч статью по влиянию грибов на сукцессию
anaschu 13.03.2026
прикрепляю статью
SDL3 для Desktop (MinGW): Создаём пустое окно с нуля для 2D-графики на SDL3, Си и C++
8Observer8 10.03.2026
Содержание блога Финальные проекты на Си и на C++: hello-sdl3-c. zip hello-sdl3-cpp. zip Результат:
Установка CMake и MinGW 13.1 для сборки С и C++ приложений из консоли и из Qt Creator в EXE
8Observer8 10.03.2026
Содержание блога MinGW - это коллекция инструментов для сборки приложений в EXE. CMake - это система сборки приложений. Здесь описаны базовые шаги для старта программирования с помощью CMake и. . .
Как дизайн сайта влияет на конверсию: 7 решений, которые реально повышают заявки
Neotwalker 08.03.2026
Многие до сих пор воспринимают дизайн сайта как “красивую оболочку”. На практике всё иначе: дизайн напрямую влияет на то, оставит человек заявку или уйдёт через несколько секунд. Даже если у вас. . .
Модульная разработка через nuget packages
DevAlt 07.03.2026
Сложившийся в . Net-среде способ разработки чаще всего предполагает монорепозиторий в котором находятся все исходники. При создании нового решения, мы просто добавляем нужные проекты и имеем. . .
Модульный подход на примере F#
DevAlt 06.03.2026
В блоге дяди Боба наткнулся на такое определение: В этой книге («Подход, основанный на вариантах использования») Ивар утверждает, что архитектура программного обеспечения — это структуры,. . .
Управление камерой с помощью скрипта OrbitControls.js на Three.js: Вращение, зум и панорамирование
8Observer8 05.03.2026
Содержание блога Финальная демка в браузере работает на Desktop и мобильных браузерах. Итоговый код: orbit-controls-threejs-js. zip. Сканируйте QR-код на мобильном. Вращайте камеру одним пальцем,. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru