Форум программистов, компьютерный форум, киберфорум
C# для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.63/16: Рейтинг темы: голосов - 16, средняя оценка - 4.63
28 / 28 / 11
Регистрация: 08.08.2011
Сообщений: 1,173

Как организовать чтение массива из четырех потоков?

06.03.2014, 19:24. Показов 3768. Ответов 38
Метки нет (Все метки)

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

Пишу программу, которая будет проверять файлы на 50 видов ошибок. Упрощенно алгоритм представляю себе следующим образом:

1. Файл читается в массив.

2. Создается 4 потока, которыми начинаются делать одновременно 4 проверки (из 50). Каждая из этих проверок читает массив и ищет конкретные виды ошибок. Результат пишется в общий dataGridView (название файла - список ошибок).

3. Когда какая-нибудь проверка отработала, вместо нее должна запускаться следующая проверка. До тех пор, пока все 50 не отработают на этом файле.

Подскажите, как лучше все это организовать? Соответственно, мне нужно из 4-х потоков одновременно обращаться (на чтение) к одному массиву, а потом писать в общий DataGridView.
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
06.03.2014, 19:24
Ответы с готовыми решениями:

Организовать чтение массива из файла, и запись массива в файл
Доброго времени суток! Как организовать чтение массива из файла и вывести массив в файл?

Как организовать создание потоков?
Подскажите pls как правильно организовать создание потоков если заранее неизвестно сколько их будет но алгоритм работы каждого потока ...

Как организовать пул потоков
Нужно реализовать многопоточную программу (+1к потоков) на C.Реализации при помощи циклов и .get слишком затруднительны.Есть массив с...

38
Master of Orion
Эксперт .NET
 Аватар для Psilon
6102 / 4958 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
30.03.2014, 19:52
Студворк — интернет-сервис помощи студентам
Suppir, значит не везде меняете, все просто.
0
28 / 28 / 11
Регистрация: 08.08.2011
Сообщений: 1,173
30.03.2014, 20:01  [ТС]
Да, точно, спасибо.

А еще вопрос. Допустим, я хочу использовать не List<string>, а string[], то есть простой массив строк. Тогда нужно что прописать вместо IList<string> прописать?
0
Master of Orion
Эксперт .NET
 Аватар для Psilon
6102 / 4958 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
30.03.2014, 20:02
Suppir, ничего, string[] и List<string> оба наследуют от IList<string>
1
28 / 28 / 11
Регистрация: 08.08.2011
Сообщений: 1,173
30.03.2014, 20:05  [ТС]
Да, точно, спасибо
0
Master of Orion
Эксперт .NET
 Аватар для Psilon
6102 / 4958 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
30.03.2014, 20:06
Suppir, в этом как бы и смысл использования ООП и интерфейсов вместо конкретных классов)
0
28 / 28 / 11
Регистрация: 08.08.2011
Сообщений: 1,173
30.03.2014, 22:04  [ТС]
Цитата Сообщение от Psilon Посмотреть сообщение
Suppir, в этом как бы и смысл использования ООП и интерфейсов вместо конкретных классов)
Еще проблема возникла.

Мне нужно в методе Check1() использовать глобальную переменную, объявленную выше Main(). Если Check1() является Static-методом, то не получается использовать эту глобальную переменную. Я меняю Static на Private, но тогда пишет:

Ошибка 1 Для нестатического поля, метода или свойства "threadtest.Program.Check1(System.Collec tions.Generic.IList<string>)" требуется ссылка на объект

Я пробую самому методу CheckAsync (из которого вызывается Check1) поменять Static на Private, но получается ошибка:

Ошибка 1 Для нестатического поля, метода или свойства "threadtest.Program.CheckAsync(System.Co llections.Generic.IList<string>, params System.Predicate<System.Collections.Gene ric.IList<string>>[])" требуется ссылка на объект

Вопрос: что нужно прописать, чтобы в методах Check1() и Check2() можно было использовать глобальные переменные (даже без изменения этих переменных, просто для чтения)?
0
Master of Orion
Эксперт .NET
 Аватар для Psilon
6102 / 4958 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
30.03.2014, 22:31
а какой-то код будет? Я плохо телепатю.

Добавлено через 31 секунду
Только не простыню в 1000 строк, а конкретные места.
0
28 / 28 / 11
Регистрация: 08.08.2011
Сообщений: 1,173
30.03.2014, 23:10  [ТС]
Вот тестовый код для примера. Сейчас пишет ошибку на вызове CheckAsync():

Ошибка 1 Для нестатического поля, метода или свойства "threadtest.Program.CheckAsync(System.Co llections.Generic.IList<string>, params System.Predicate<System.Collections.Gene ric.IList<string>>[])" требуется ссылка на объект


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
using System;
using System.IO;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
 
namespace threadtest
{
    class Program
    {
        Regex re1 = new Regex("бла-бла", RegexOptions.Compiled);
        Regex re2 = new Regex("хрю-хрю", RegexOptions.Compiled);
 
        static void Main()
        {
            Console.WriteLine("Читаю файл...");
            string[] file = File.ReadAllLines("c:\\1.txt", Encoding.GetEncoding(866));
            var allChecksCompleted = CheckAsync(file, Check1, Check2);
            Console.WriteLine("Успешные проверки: ");
            foreach (var predicate in allChecksCompleted)
            {
                Console.WriteLine(predicate.Method.Name);
            }
        }
 
        private IList<Predicate<IList<string>>> CheckAsync(IList<string> file, params Predicate<IList<string>>[] predicates)
        {
            var result = new List<Predicate<IList<string>>>(predicates.Length);
            var allDone = new ManualResetEvent(false);
            int completed = 0;
            foreach (var p in predicates)
            {
                Predicate<IList<string>> currentCheck = p;
                ThreadPool.QueueUserWorkItem(_ =>
                {
                    if (currentCheck(file))
                        lock (result)
                        {
                            result.Add(currentCheck);
                        }
                    if (Interlocked.Increment(ref completed) == predicates.Length)
                        allDone.Set();
                });
            }
            allDone.WaitOne();
            return result;
        }
 
        private bool Check1(IList<string> file)
        {
            foreach (string line in file)
            {
                if (re1.IsMatch(line))
                { 
                
                }
            }
            return true;
        }
        private bool Check2(IList<string> file)
        {
            foreach (string line in file)
            {
                if (re2.IsMatch(line))
                {
 
                }
            }
            return true;
        }
 
    }
}
0
Master of Orion
Эксперт .NET
 Аватар для Psilon
6102 / 4958 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
30.03.2014, 23:15
во-первых проверка не просто так была в другом классе.

Во-вторых, вам нужно книжечки по программировании видимо почитать, у вас путаница в простейших понятиях

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
using System;
using System.IO;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
 
namespace threadtest
{
    class Program
    {
        static Regex re1 = new Regex("бла-бал", RegexOptions.Compiled);
        static Regex re2 = new Regex("хрю-хрю", RegexOptions.Compiled);
 
        static void Main()
        {
            Console.WriteLine("Читаю файл...");
            string[] file = File.ReadAllLines("c:\\1.txt", Encoding.GetEncoding(866));
            var allChecksCompleted = MultithreadChecker.CheckAsync(file, Check1, Check2);
            Console.WriteLine("Успешные проверки: ");
            foreach (var predicate in allChecksCompleted)
            {
                Console.WriteLine(predicate.Method.Name);
            }
        }
 
        private static bool Check1(IList<string> file)
        {
            foreach (string line in file)
            {
                if (re1.IsMatch(line))
                {
 
                }
            }
            return true;
        }
        private static bool Check2(IList<string> file)
        {
            foreach (string line in file)
            {
                if (re2.IsMatch(line))
                {
 
                }
            }
            return true;
        }
    }
 
    public static class MultithreadChecker
    {
        public static IList<Predicate<IList<string>>> CheckAsync(IList<string> file, params Predicate<IList<string>>[] predicates)
        {
            var result = new List<Predicate<IList<string>>>(predicates.Length);
            var allDone = new ManualResetEvent(false);
            int completed = 0;
            foreach (var p in predicates)
            {
                Predicate<IList<string>> currentCheck = p;
                ThreadPool.QueueUserWorkItem(_ =>
                {
                    if (currentCheck(file))
                        lock (result)
                        {
                            result.Add(currentCheck);
                        }
                    if (Interlocked.Increment(ref completed) == predicates.Length)
                        allDone.Set();
                });
            }
            allDone.WaitOne();
            return result;
        }
    }
}
1
28 / 28 / 11
Регистрация: 08.08.2011
Сообщений: 1,173
30.03.2014, 23:17  [ТС]
Насколько я понял, ошибка в том, что из статического Main() вызывается private CheckAsync. Но main() в консольном приложении всегда статический по умолчанию. Что с этим делать, не совсем понятно.

Добавлено через 1 минуту
Цитата Сообщение от Psilon Посмотреть сообщение
Во-вторых, вам нужно книжечки по программировании видимо почитать,
Да, нужно, конечно Вообще, я книг 7 полностью прочитал, но только по Perl. А в c# надеялся методом тыка разобраться Без ООП все понятно (т.к. в Perl очень мало ООП используется), а вот с ООП слабовато выходит.
0
Master of Orion
Эксперт .NET
 Аватар для Psilon
6102 / 4958 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
30.03.2014, 23:19
Suppir, ошибка в том, что статические методы пытаются вызвать нестатический Regex. У вас нет объектов класса Program, поэтому все его поля должны быть статическими. В следующий раз чтобы такой ошибки не возникало дописывайте static class Program и он подчеркнет ошибки.

Шилдта обязательно почитайте. Иначе "методом тыка" дотыкаетесь до быдлокода.
0
28 / 28 / 11
Регистрация: 08.08.2011
Сообщений: 1,173
30.03.2014, 23:24  [ТС]
Psilon, насколько знаю, статический метод работает быстрее чем private или public. Как думаете, что будет быстрей работать:
использовать нестатический Regex, определенный вверху программы, или заново определить Regex внутри статического метода?
0
Master of Orion
Эксперт .NET
 Аватар для Psilon
6102 / 4958 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
30.03.2014, 23:27
Suppir, пишите так, как считаете правильонее. А если будет работать медленно, тогда можно будет подумать об оптимизации. Оптимизации всегда ухудшают код, поэтому без необходимости ими лучше не заниматься.

Вообще лучше использовать такой класс:
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
    public static class MultithreadChecker
    {
        public static IList<Predicate<IList<string>>> CheckAsync(IList<string> file, params Predicate<IList<string>>[] predicates)
        {
            var result = new List<Predicate<IList<string>>>(predicates.Length);
            var allDone = new ManualResetEvent(false);
            int completed = 0;
            foreach (var p in predicates)
            {
                Predicate<IList<string>> currentCheck = p;
                ThreadPool.QueueUserWorkItem(_ =>
                {
                    if (currentCheck(file))
                        lock (result)
                        {
                            result.Add(currentCheck);
                        }
                    if (Interlocked.Increment(ref completed) == predicates.Length)
                        allDone.Set();
                });
            }
            allDone.WaitOne();
            return result;
        }
 
        public static IList<string> CheckAsyncRegex(string file, params string[] patterns)
        {
            var result = new List<string>(patterns.Length);
            var allDone = new ManualResetEvent(false);
            int completed = 0;
            foreach (var p in patterns)
            {
               var currentCheck = p;
                var regex = new Regex(currentCheck, RegexOptions.Compiled);
                ThreadPool.QueueUserWorkItem(_ =>
                {
                    if (regex.IsMatch(file))
                        lock (result)
                        {
                            result.Add(currentCheck);
                        }
                    if (Interlocked.Increment(ref completed) == patterns.Length)
                        allDone.Set();
                });
            }
            allDone.WaitOne();
            return result;
        }
    }
можете использовать CheckAsyncRegex чтобы с помощью регулярок проверять файл.В данном случае я передаю файл как одну строку, при желании можете переделать на IList<string>, хотя не вижу в этом смысла, лучше прочитать весь файл в одну строку же.

Добавлено через 52 секунды
а проверять можно так:
C#
1
2
string file = File.ReadAllText("c:\\1.txt", Encoding.GetEncoding(866));
var allChecksCompleted = MultithreadChecker.CheckAsyncRegex(file, "бла-бал", "хрю-хрю");
1
28 / 28 / 11
Регистрация: 08.08.2011
Сообщений: 1,173
30.03.2014, 23:38  [ТС]
Понятно. Эти регулярки я для примера написал, на самом деле там гораздо более сложные проверки (40 проверок, в каждой от 50 до 300 строк кода). Сейчас это отдельные программы и скрипты (40 программ), я хочу все объединить в один framework, который будет многопоточно делать эти проверки на большом количестве файлов.

Добавлено через 8 минут
Например, вот регексы только одной программы (а всего 40 программ):
Миниатюры
Как организовать чтение массива из четырех потоков?  
0
Master of Orion
Эксперт .NET
 Аватар для Psilon
6102 / 4958 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
30.03.2014, 23:40
Suppir, я должен ужаснуться или что?
Тем более используйте второй метод вместо первого. Просто укажите через запятую текст регулярок (только удостоверьтесь, что паттерны правильные), остальное сделает метод CheckAsyncRegex
0
28 / 28 / 11
Регистрация: 08.08.2011
Сообщений: 1,173
30.03.2014, 23:44  [ТС]
Да там не просто файл проверяется набором регексами. Я ж говорю, что для примера написал.
Там сложный парсинг каждого файла + различные проверки (в том числе с использованием регексов). Спасибо за пример кода, буду разбираться.
0
28 / 28 / 11
Регистрация: 08.08.2011
Сообщений: 1,173
24.05.2014, 14:17  [ТС]
Psilon, вопрос такой возник:

как вместо параметров check1 и check2 послать в метод List<string>, содержащий эти параметры?

То есть я сделал treeview с чекбоксами, пользователь натыкал нужные ему чекбоксы; я получил имена отмеченных чекбоксов, а теперь - нужно послать эти имена списком в ваш метод. Как это сделать?


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
        CheckAsync(lines, check1, check2);
 
        ...
 
        private IList<Predicate<IList<string>>> CheckAsync(IList<string> file, params Predicate<IList<string>>[] predicates)
        {
            var result = new List<Predicate<IList<string>>>(predicates.Length);
            var allDone = new ManualResetEvent(false);
            int completed = 0;
            foreach (var p in predicates)
            {
                Predicate<IList<string>> currentCheck = p;
                ThreadPool.QueueUserWorkItem(_ =>
                {
                    if (currentCheck(file))
                        lock (result)
                        {
                            result.Add(currentCheck);
                        }
                    if (Interlocked.Increment(ref completed) == predicates.Length)
                        allDone.Set();
                });
            }
 
            allDone.WaitOne();
            return result;
        }
Добавлено через 8 минут
Имена чекбоксов совпадают с названиями вызываемых методов.

Добавлено через 9 минут
Идея понятна: пользователь выбирает чекбоксами нужные проверки, а они потом запускаются через этот метод многопоточно.
0
Master of Orion
Эксперт .NET
 Аватар для Psilon
6102 / 4958 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
24.05.2014, 14:18
Suppir, никак, этот класс другую цель имеет. Вспоминаем принцип единой ответственности. Вместо одного супер-пупер класса-комбайна напишите еще один, который будет с формой работать. Этот метод вообще смысла курочить нет, он и так максимально масштабируемо написан.

Для самопроверки добавьте в солюшн 3 проекта: консоль, формочку и библиотечку, где будет лежать этот класс.

А теперь и форма и консоль должны ссылаться на одну эту библиотеку, и одинаково работать. Если прибить гвоздями к чекбоксам код, он явно так работать не будет...
0
28 / 28 / 11
Регистрация: 08.08.2011
Сообщений: 1,173
24.05.2014, 14:50  [ТС]
Ну, я написал метод, который получает имена отмеченных чекбоксов. Получился List<string>, содержащий, допустим, check1 и check2.

Теперь нужно отправить этот список (содержащий check1 и check2) на комбайн.

Смысл в том, что разные чекбоксы могут быть отмечены, не могу придумать, как посылать на комбайн именно отмеченные?

Добавлено через 28 минут
Короче, я добавил в сами методы Check1, Сheck2 и т.д. в самом начале проверки:
если соответствующий чекбокс выключен, то сразу возвращается true.

И на CheckAsync() сразу посылаю все методы. Правда, совсем не уверен, что это правильное решение в плане скорости.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
24.05.2014, 14:50

Как организовать корректную работу потоков с одним файлом
private void button1_Click(object sender, EventArgs e) { for (int p = 0; p &lt; 2; p++) { ...

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

Найти сумму четырех наибольших и четырех наименьших элементов массива
Привет помогите пожалуйста решить несколько задачек... 1.Дан массив из 25элементов, найти сумму четырех наибольших и четырех...

Найти сумму четырёх наибольших и четырёх наименьших элементов массива
Дан массив из 25 элементов найти сумму 4 наибольших х четырех наименьших элементов Результат распечатать в виде: Массив: Сумма...

Как организовать чтение из потока?
Задача стоит в том, как из потока считывать по два бита и записывать в элемент массива по два считанных бита. Массив типа char.


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

Или воспользуйтесь поиском по форуму:
39
Ответ Создать тему
Новые блоги и статьи
Программный домашний кинотеатр
russiannick 27.09.2026
Сподобился на программный домашний кинотеатр. В качестве ЯВУ по традиции выбрал js. В помощники взял Яндекс-Алису. Было создано три зала на разные интересы. исторические и ретро сериал Хичкок. . .
Беседа с ИИ о программистах, недопускающих к созданию и правке кода генеративные ИИ и причины этого
zorxor 21.09.2026
Раньше я радовался или получал некоторые эмоции, пусть небольшие, но всё же, от самого процесса написания кода, рекомпиляции и запуска, видя постепенное развитие программы и прочее. А теперь лень. . .
Мобильное приложение ColorStep
pavlinmavlin 17.09.2026
Реализовал приложение Красный, Зеленый, Синий в Unity3d + c#. Название изменил на ColorStep. Приложение прошло модерацию и теперь доступно для скачивания. Делал его сам, шаг за шагом — и вот,. . .
Запрет дублирования строк в табличной части
Maks 13.09.2026
Реализация из решения ниже выполнена на нетиповом справочнике "Нормы ТО" с табличной часть "Виды ТО", разработанного в КА2, со следующими реквизитами: - ВидТО (СправочникСсылка. ВидыТО); - ВидГСМ. . .
Скрипты 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: Математический инвариант ОДУ и рок Стивов-бонобо Главная задача разработанной «Модели Всего» — наглядно продемонстрировать наличие системной «судьбы». . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru