Форум программистов, компьютерный форум, киберфорум
C# .NET
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.62/13: Рейтинг темы: голосов - 13, средняя оценка - 4.62
 Аватар для awp-sirius
64 / 63 / 43
Регистрация: 01.05.2012
Сообщений: 535
.NET 4.x

И снова многопоточность

01.06.2014, 02:13. Показов 3001. Ответов 36
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Доброй ночи всем!

Я уже понял, что это ооочень заезженная тема "многопоточность")

Полностью просмотрел урок (2 часа) http://www.youtube.com/watch?v=strsTAfcAv4

Основы-то понял, но как именно реализовать мою задачу пока не совсем понимаю...
А задача в следующем:
Имеется какой-то длинный массив строк. Ну и используем к примеру 10 потоков.

Должно происходить что-то следующее:
1-й поток берёт себе 1-ю строку массива, 2-й вторую и так далее. НО время выполнения может быть разное, и если первые 9 потоков ещё выполняют задачу, а 10-й поток уже выполнил мвою 10-ю строку, то он должен брать следующую строку массива (11-ю).
И так соответственно все остальные. (Не блещу умением объяснять))

Короче: что бы когда поток выполняет какое-то действие с элементом массива, он должен брать следующий первый попавшийся.

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

Весь день читаю статьи и не могу точно найти ответ на поставленную задачу. И при помощи чего делать..
Почему-то кажется что подойдёт пул потоков.. Или может через Parallel.For?

Скорее всего буду делать WidowsForms, поэтому может быть использовать BackgroundWorker?..

В общем подскажите пожалуйста... Уже очень долго мучаюсь..

P.S. Заранее отвечу на вопрос, программа ProxyChecker.. Просто встала задача под определённый сайт. Саму проверку прокси уже реализовал, вот теперь мучаюсь, что бы ускорить сее творение.
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
01.06.2014, 02:13
Ответы с готовыми решениями:

И снова про многопоточность
Доброго времени суток, форумчане, задался целью немного переделать программу для более быстрой работы Итак, что мы имеем: массив картинок...

Снова многопоточность: совместный доступ к объекту
Добрый день. Начал самостоятельно изучать Java. Дойдя до вопросов многопоточности, решил написать тестовую программу, в которой класс...

Снова хром, снова сапопроизвольно открывается, снова bkrfdf.xyz и казино
Здравствуйте! Собственно, проблема уже не новая, хотя, как показывают сообщения форума, за последние дни выскочившая у многих. Через...

36
Master of Orion
Эксперт .NET
 Аватар для Psilon
6102 / 4958 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
01.06.2014, 19:43
Лучший ответ Сообщение было отмечено awp-sirius как решение

Решение

Студворк — интернет-сервис помощи студентам
awp-sirius, Parallel гарантирует именно ту модель поведения, которую вы предлагаете.
Он создает N потоков и дает им первые N элементов на обработку. Если какой-то поток закончил работу, то ему дается следующий по очереди элемент массива. И так до тех пор, пока массив не кончится. Один "быстрый" поток может сделать 3 задачи, в то время как один "медленный" выполнит тем делом только одну. Только вот не принимайте разработчиков за дураков, они не стали бы делать АПИ, которым никто не стал бы пользоваться, а если бы был возможен доступ к одному элементу массива дважды, так оно и было бы.

ThreadPool.SetMaxThreads(int workerThreads, int completionPortThreads), но что такое int completionPortThreads?
На msdn написано, но как-то не понятно..
Этот метод вообще лучше не трогайте. Задавать максимальное число потоков нужно так:
C#
1
 Parallel.For(1, 100, new ParallelOptions {MaxDegreeOfParallelism = 4}, Console.WriteLine); //Использовать не более 4 потоков
1
169 / 132 / 29
Регистрация: 16.02.2013
Сообщений: 867
01.06.2014, 21:06
Цитата Сообщение от Psilon Посмотреть сообщение
вручную, это new Thread()
а какие это... преимущества что ли, у пула, от ручного создания потоков? В пуле можно потоки завершать? Я знаю, что нельзя Создавал уже тему - Потоки не сразу убиваются (или так надо?) , сейчас программы у меня работают через "костыль" - остановка потоков происходит лишь "визуально", и они еще работают некоторое время, если попадется прокси сервер медленный. А как жить то?

Цитата Сообщение от Psilon Посмотреть сообщение
Только вот не принимайте разработчиков за дураков, они не стали бы делать АПИ, которым никто не стал бы пользоваться, а если бы был возможен доступ к одному элементу массива дважды, так оно и было бы.
так почему бы тогда не использовать сторонние либы, написанные другими разработчиками? Ну к примеру - xNet, Viking.Engine(о которой не очень хорошие отзывы тру кодеров)?
0
 Аватар для awp-sirius
64 / 63 / 43
Регистрация: 01.05.2012
Сообщений: 535
01.06.2014, 21:36  [ТС]
Psilon, Огромное спасибо, выручаете меня уже не первый раз!

Только вот проблема с переменными...
Как я понял там, где у вас написано "Console.WriteLine" пишется метод, который выполняется для текущего числа (в вашем примере от 1 до 100). Для меня тоесть это номер сроки массива.


Но, когда выполняется вторичный поток он знает только № этой строки, а само значение из массива извлечь не может..
Как мне передать в метод Check сам массив string[] NewProxy = richTextBox1.Lines.ToArray()?
Так же проблема наоборот. Если прокси валидный, нужно его записать в richTextBox2, а там ошибка мол richTextBox2 создан в другом потоке.
На сколько понимаю это делается как-то при помощи Invoke, но на этом знание заканчивается....

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
public Form1()
        {
            InitializeComponent();
        }
 
        string[] Proxy;
 
        public void button1_Click(object sender, EventArgs e)
        {
            richTextBox1.Enabled = false;
 
            
            string[] NewProxy = richTextBox1.Lines.ToArray();
 
            
            Parallel.For(0, NewProxy.Length, new ParallelOptions { MaxDegreeOfParallelism = 10 }, Check);
 
            richTextBox1.Enabled = true;
        }
 
 
        static void Check(int i)
        {
            using (var Request = new HttpRequest())
            {
                try
                {
                    Request.CharacterSet = System.Text.Encoding.GetEncoding("UTF-8");
                    Request.Proxy = HttpProxyClient.Parse(NewProxy[i]);
                    string SourcePage = Request.Get("http://auto.ru").ToString();
                    string logo = SourcePage.Substrings("<img id=\"logo-pic\" src=\"", "\" width=\"79\" height=\"19", 0)[0];
 
                    if (logo == "http://i.auto.ru/design/2012/img/autoru-logo-i.png")
                    {
                        //richTextBox2.Text += NewProxy[i] + "\n";
                        MessageBox.Show("Прокси валид");
                    }
                }
                catch
                {
                    MessageBox.Show("Прокси невалид");
                }
 
 
            }
 
        }
Добавлено через 2 минуты
естественно проблема на 29 строке

Добавлено через 6 минут
с выводом вроде разобрался:

C#
1
this.richTextBox2.Text = i + "\n";
Добавлено через 13 минут
Хотя нет... Не разобрался. Запись-то идёт, но иногда выскакивает ошибка мол обращение из 2-х потоков...
lock как-то не помогает почему-то =(

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
object block = new object();
 
        public Form1()
        {
            InitializeComponent();
        }
 
        public void button1_Click(object sender, EventArgs e)
        {
            richTextBox1.Enabled = false;
            
            string[] NewProxy = richTextBox1.Lines.ToArray();
            
            Parallel.For(0, NewProxy.Length, new ParallelOptions { MaxDegreeOfParallelism = 10 }, Print);
 
            richTextBox1.Enabled = true;
        }
 
        public void Print(int i)
        {
            lock (block)
            {
                this.richTextBox2.Text += i + "\n";
            }
        }
0
169 / 132 / 29
Регистрация: 16.02.2013
Сообщений: 867
01.06.2014, 22:18
Цитата Сообщение от awp-sirius Посмотреть сообщение
Хотя нет... Не разобрался. Запись-то идёт, но иногда выскакивает ошибка мол обращение из 2-х потоков...
Control.Invoke Method (Delegate)
0
Master of Orion
Эксперт .NET
 Аватар для Psilon
6102 / 4958 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
01.06.2014, 23:32
awp-sirius, используй Parallel.ForEach вместо Parallel.For

Цитата Сообщение от Winhttp22 Посмотреть сообщение
а какие это... преимущества что ли, у пула, от ручного создания потоков? В пуле можно потоки завершать? Я знаю, что нельзя Создавал уже тему - Потоки не сразу убиваются (или так надо?) , сейчас программы у меня работают через "костыль" - остановка потоков происходит лишь "визуально", и они еще работают некоторое время, если попадется прокси сервер медленный. А как жить то?
Потоки как правило не нужно завершать А преимущества - то, что слишком много потоков - вся производительность будет убиваться на переключение контекста. В общем почитайте, зачем вообще нужны "пулы" объектов, что потоков, что памяти, что чего-нибудь еще
0
169 / 132 / 29
Регистрация: 16.02.2013
Сообщений: 867
02.06.2014, 00:20
Цитата Сообщение от Psilon Посмотреть сообщение
Потоки как правило не нужно завершать
ну это не всегда.
Цитата Сообщение от Psilon Посмотреть сообщение
В общем почитайте, зачем вообще нужны "пулы" объектов, что потоков, что памяти, что чего-нибудь еще
да, нужно почитать, подтянуть знания Правда мне не жаловались пока на плохую производительность программ . Но если производительность станет лучше - то почему бы и нет?))
0
Master of Orion
Эксперт .NET
 Аватар для Psilon
6102 / 4958 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
02.06.2014, 00:53
Winhttp22, просто нет смысла делать хуже, если лучше сделать не сложнее

ну это не всегда.
остановку потока легко можно сделать внутри метода поточного. Thread.Abort() вообще считается редскостной какашкой, и абсолютно не рекомендуется его использовать. Ну а без него разницы нет, а та, что есть, не в тему Thread'а

http://stackoverflow.com/quest... read-abort

Добавлено через 2 минуты
советую прочитать все ответы целиком, но краткая выдержка от Эрика:
In short, Thread.Abort is at best indicative of bad design, possibly unreliable, and extremely dangerous. It should be avoided at all costs; the only time you should ever even consider aborting a thread is in some sort of "emergency shutdown" code where you are attempting to tear down an appdomain as cleanly as possible.
0
 Аватар для awp-sirius
64 / 63 / 43
Регистрация: 01.05.2012
Сообщений: 535
02.06.2014, 01:15  [ТС]
Не могу въехать.....

ForEach<TSource>(IEnumerable<TSource>, Action<TSource, ParallelLoopState>)
Что там есть что.. Везде написано мудрёно...

Можно хотя бы пример как сделать из

C#
1
2
3
4
5
string[] NewProxy = richTextBox1.Lines.ToArray();
            foreach (string i in NewProxy)
            {
                richTextBox2.Text += i + "\n";
            }
Тоже самое, только многопотоковое Parallel.ForEach. Пусть даже будет не по порядку.....
0
Master of Orion
Эксперт .NET
 Аватар для Psilon
6102 / 4958 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
02.06.2014, 01:30
awp-sirius,
C#
1
2
string[] text = "Что там есть что.. Везде написано мудрёно... Можно хотя бы пример как сделать из".Split();
Parallel.ForEach(text, s => Console.WriteLine(s));
Добавлено через 1 минуту
awp-sirius, блин, забудьте про текстбоксы и прочее. Вся многопоточность должна работать с внутренними списками и массивами, и не обращаться к элементам формы. В лучшем случае получете ошибку "доступ к компоненту не из потока, в котором он был создан", а в худшем - трудноуловимый баг.
0
 Аватар для awp-sirius
64 / 63 / 43
Регистрация: 01.05.2012
Сообщений: 535
02.06.2014, 01:49  [ТС]
Psilon, Получается список валидных прокси можно будет получить только по окончанию всей проверки...
А как тогда делают подобные программы? Каждый проверенный сразу появляется в текстбоксе..
Может подключить BackgroungWorker?

Добавлено через 12 минут
Почему вот таким способом не получается сделать?...

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
        object block = new object();
 
        public void button1_Click(object sender, EventArgs e)
        {
            richTextBox1.Enabled = false;
 
            string[] NewProxy = richTextBox1.Lines.ToArray();
            Parallel.ForEach(NewProxy, new ParallelOptions { MaxDegreeOfParallelism = 10 }, s => { Print(s); });
 
            richTextBox1.Enabled = true;
        }
 
        public void Print(string s)
        {
            lock (block)
            {
                richTextBox2.Text += s + "\n";
            }
        }
не срабатывает lock...
0
Master of Orion
Эксперт .NET
 Аватар для Psilon
6102 / 4958 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
02.06.2014, 01:51
awp-sirius, они вызывают событие. А на событие подписывается формочка, и уже сама отображает в своем потоке. Это называется ООП и принцип единой ответственности

Добавлено через 1 минуту
хотя бы так:
C#
1
2
3
4
5
6
7
8
9
10
11
        public void Print(string s)
        {
            if (InvokeRequired)
            {
                Invoke(new Action(() => Print(s)));
            }
            else
            {
                richTextBox2.Text += s + "\n";
            }
        }
0
 Аватар для awp-sirius
64 / 63 / 43
Регистрация: 01.05.2012
Сообщений: 535
02.06.2014, 02:46  [ТС]
Цитата Сообщение от Psilon Посмотреть сообщение
хотя бы так: ...........
= Если метод Print уже исполняется, то начать выполнять метод сначала?
или же записать в бокс?



Сейчас проверил... Нет.. Видно какие-то потоки зацикливаются..
После выполнения форма неактивна

Добавлено через 23 минуты
Господи, когда же я уже сделаю это.....

Добавлено через 10 секунд


Добавлено через 24 минуты
вот так вроде пашет:
C#
1
2
if (richTextBox2.InvokeRequired) richTextBox2.BeginInvoke(new Action<string>((s) => Print(s)), n);
else richTextBox2.Text += n + "\n";
только меня смущает то, что вы написали "хотя бы так:" тоесть этот способ не очень хорош?
0
192 / 199 / 82
Регистрация: 11.04.2013
Сообщений: 1,086
02.06.2014, 07:28
Цитата Сообщение от awp-sirius Посмотреть сообщение
только меня смущает то, что вы написали "хотя бы так:" то есть этот способ не очень хорош?
Потому что Invoke прерывает выполнение потока на время вывода данных и только после этого поток продолжает свою работу
0
 Аватар для awp-sirius
64 / 63 / 43
Регистрация: 01.05.2012
Сообщений: 535
02.06.2014, 18:50  [ТС]
Подскажите, как выполнить поставленную задачу правильно?....
Мне кажется нужно всё же использовать backgroundWorker...
0
Master of Orion
Эксперт .NET
 Аватар для Psilon
6102 / 4958 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
02.06.2014, 19:10
awp-sirius, я же уже сказал парой постов назад Всю логику по пингу (или что там у вас) и прочему вообще желательно поместить библиотеку, в которой не должно быть никаких System.Windows.Forms и так далее. Там нужно объявить класс, который будет пинговать и по результатам этих пингов вызывать событие Ping_successed. В это время форма должна подписаться на это событие, ну а в самом событии уже с помощью BeginInvoke отображать результаты на форме.
0
 Аватар для awp-sirius
64 / 63 / 43
Регистрация: 01.05.2012
Сообщений: 535
02.06.2014, 22:23  [ТС]
Ладно если откинуть форму вообще. Список прокси из файла записываем в массив.


Просто я не понимаю.... Parallel.ForEach требует статический метод...
И как можно из него что-то куда-то записать.............?

Добавлено через 12 минут
Будет ли такой вариант правильным??

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
namespace Console_Proxy
{
    class Program
    {
        static void Main(string[] args)
        {
            StringCollection EditProxy = new StringCollection();
 
            string[] NewProxy = { "19", "8.", "27.1", "25", ".222:", "78", "08", "212.", "154.1", "54", ".220:", "80", "80", "209", ".129", ".24", "4.6:", "80" };
 
            Parallel.ForEach(NewProxy, new ParallelOptions { MaxDegreeOfParallelism = 100 }, n => Check(n, EditProxy));
 
            foreach (Object obj in EditProxy) Console.WriteLine(obj);
 
            Console.ReadLine();
        }
 
 
        static void Check(string n, StringCollection EditProxy)
        {
            if (n.Length == 4)
            {
                EditProxy.Add(n);
            }
        }
    }
}
Если честно не понимаю, почему программа не ругается на использование EditProxy из разных потоков одновременно.... Можете объяснить?
0
 Аватар для Spawn
995 / 893 / 354
Регистрация: 24.03.2014
Сообщений: 2,381
Записей в блоге: 2
02.06.2014, 23:35
Цитата Сообщение от awp-sirius Посмотреть сообщение
Просто я не понимаю.... Parallel.ForEach требует статический метод...
Ну, Вы в принципе в статическом методе находитесь, о каком экземплярном речь?)
Цитата Сообщение от awp-sirius Посмотреть сообщение
И как можно из него что-то куда-то записать.............?
События, как уже выше написали... пару раз.
Цитата Сообщение от awp-sirius Посмотреть сообщение
Если честно не понимаю, почему программа не ругается на использование EditProxy из разных потоков одновременно.... Можете объяснить?
А на что ей ругаться? Можете это хоть потокобезопасностью обозвать, не на что ей просто ругаться. Ваша коллекция в отличие от "окошек" Windows не требует DispatchMessage и очереди сообщений для нормального функционирования, так что жаловаться особо не на что. Жаловаться будет на что скорее Вам, если отсутствует синхронизация, но предполагается.
3
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
02.06.2014, 23:35

Как сделать чтобы таймер дойдя до 0 стартовал снова и снова?
Здравствуйте :) Как сделать чтобы таймер дойдя до 0 стартовал снова и снова? TimerSec = 59; TimerMin = 6; for(int i = TimerSec;...

HP 625 снова и снова перезагружается в безопасный не заходит
Ребята помогите , проблема вот какая врубаю я ноут он доходит до заставки майкрософта и снова перезагружается в безопасный не заходит, ...

Снова поток. Снова синхронизация
Приветствую всех. Тема измусолена до дыр, поэтому прошу не пинать. В программе создан поток. В каких случаях поток может работать с...

и снова .htaccess и снова rewriterule
Добрый день. Недавно столкнулся с проблемой преобразования URL, в связи с чем пришлось перерыть кучу материала по данной теме, но вопрос...

Снова. Снова этот repaint()
Всем привет. Сколько дней уже пытаюсь, нечего не выходит. Метод repaint не срабатывает. Как я понимаю, ошибка появляется в методе redraw...


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

Или воспользуйтесь поиском по форуму:
37
Ответ Создать тему
Новые блоги и статьи
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр.
Jin X 06.09.2026
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр. Работая с форумом и нейросетями в браузере часто хочется что-то подкорректировать или добавить какого-то функционала. Ниже прикреплён. . .
Программа опроса у.з. расходомера SLS-720F
Argus19 02.09.2026
Программа опроса у. з. расходомера SLS-720F Программа опрашивает один раз в минуту три ультразвуковых расходомера SLS-720F через интерфейс RS-485 по протоколу Modbus RTU. Опрашиваются регистры. . .
Hyper-V: Компьютер должен поддерживать доверенный платформенный модуль 2.0.
Maks 31.08.2026
При установке Windows 11 на виртуальную машину Hyper-V 2-го поколения вылезла такая ошибка: Решение: в параметрах виртуальной машины, в разделе "Безопасность" (Security) активировать флаг. . .
Архитектура биовида Стива в Майнкрафте: Зачем бонобо кубический каннибализм
anaschu 30.08.2026
Кубический Вагинокапитализм в Minecraft: Математический инвариант ОДУ и рок Стивов-бонобо Главная задача разработанной «Модели Всего» — наглядно продемонстрировать наличие системной «судьбы». . .
Оттачиваю умение писать js программы.
russiannick 30.08.2026
Проектом выходного дня стало написание Книги шифров Виженера. Итогом стала версия 200, синий туман. Синий туман назван так, потому что замораживает текст под собой. Нажатие синих кнопок управляют. . .
мат медиц модель 30. презентация проекта
anaschu 27.08.2026
хоп хоп хоп хидахоп, а я кладую))
Как у меня протекала болезнь
zorxor 27.08.2026
Здравствуйте, друзья! Эта запись блога предназначена именно для вас - для моих дорогих друзей, которые знали меня лично. Чтобы ответить на вопрос - а что же со мной произошло на самом деле? Я учился. . .
Нашел вот забавное видео о измерениях. Лучшее что я видел на эту тему
kumehtar 26.08.2026
ILETXiw9bMQ Основная суть и тезисы по измерениям: 0D (Нулевое измерение): точка, не имеющая длины, ширины, высоты или объема. Объект не может перемещаться в 0D. 1D (Первое измерение):. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru