Форум программистов, компьютерный форум, киберфорум
C# для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.78/18: Рейтинг темы: голосов - 18, средняя оценка - 4.78
0 / 0 / 2
Регистрация: 02.01.2014
Сообщений: 240
1

Взаимодействие между потоками

11.02.2015, 21:26. Показов 3207. Ответов 16
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Мне надо чтоб 1 поток перебирал числа из файла и , которые кратны 17, передавать второму потоку, который просто накапливает эти числа и выводит их на экран. Я вот написал, объясните, там компилятор говорит что я null передаю, что я не так делаю?
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
using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
 
namespace ConsoleApplication1
{
    class Program
    {
        private double suma = 0;
        private double zn = 0;
        private ThreadStart myThreadDelegate;
        private Thread thr;
        private Thread thr1;//можно ли так разбить потоки и будет ли это тогда многопоточность
        public void first()
        {
            Console.WriteLine("Поток 2 запущен");
        }
        public void Thread()
        {
            int i = 0;
            string[] readText = File.ReadAllLines(@"D:\test.txt");
            foreach (string s in readText)
            {
                zn = Convert.ToDouble(s);
                if (zn % 17 == 0)
                {
                     Resume();
                    Thread2(zn);
                    zn = 0;
                }
                i++;
                Console.Clear();
                Console.WriteLine("Обработано {0}/1000000000", i);
            }
        }
        public void Thread2(double chys)
        {
            suma += chys;
            Console.Clear();
            Console.WriteLine("Сума чисел кратных 17 ={0}", suma);
            Suspend();
        }
        public void Resume()
        {
            thr1.Resume();
        }
        public void Suspend()
        {
            thr1.Suspend();// Необработанное исключение типа "System.NullReferenceException" в ConsoleApplication1.exe
 
        }
        public void go()
        {
            ThreadStart myThreadDelegate = new ThreadStart(Thread);
            Thread thr = new Thread(myThreadDelegate);
            thr.Start();
        }
        public void go1()
        {
            ThreadStart myThreadDelegate = new ThreadStart(first);
            Thread thr1 = new Thread(myThreadDelegate);
            thr1.Start();
            Suspend();
            //thr1.Suspend();
        }
        [STAThread]
        static void Main(string[] args)
        {
            //double zn = 0;
            Program sw = new Program();
            sw.go();
            sw.go1();
            Console.ReadLine();
        }
    }
}
Я понимаю, что через одно место делаю это, но не приходит ничего в голову, как создать 2 процесс, который будет спать и только когда ему передают число, то он просыпается и прибавил число и снова спать. Если невозможно исправить мое "творение", то подскажите как это сделать разумно, желательно с примером. Заранее спасибо.
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
11.02.2015, 21:26
Ответы с готовыми решениями:

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

Обмен данными между потоками
Добрый день! Тема давно избитая и статей казалось бы много по данной теме, но не могу доконца...

Распределение информации между потоками
Здравствуйте. Представьте, есть текстовый файл, в нем 100 строк(URL адреса). Моно ли как то...

Разделение данных между потоками (теория)
Помогите понять что такое разделение данных между потоками. Изучаю статью "Работа с потоками C#"...

16
Эксперт .NET
5534 / 4298 / 1217
Регистрация: 12.10.2013
Сообщений: 12,332
Записей в блоге: 2
12.02.2015, 04:31 2
Цитата Сообщение от Mansu Посмотреть сообщение
подскажите как это сделать разумно, желательно с примером.
Наверное так.
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
using System.IO;
 
namespace ConsoleApplication4 {
    class Program {
        static void Main(string[] args) {
            int result = File.ReadAllLines(@"D:\test.txt").AsParallel().Select(s => int.Parse(s)).Count(i => i % 17 == 0);
            Console.WriteLine("Result is: {0}", result);
            Console.ReadLine();
        }
    }
}
1
0 / 0 / 2
Регистрация: 02.01.2014
Сообщений: 240
12.02.2015, 08:11  [ТС] 3
а можно без AsParallel(), я хочу простым методом, вот как я написал. Помогите пожалуйста.

Добавлено через 1 минуту
Просто хочу написать самому механизм.
0
Эксперт .NET
5534 / 4298 / 1217
Регистрация: 12.10.2013
Сообщений: 12,332
Записей в блоге: 2
12.02.2015, 08:26 4
Цитата Сообщение от Mansu Посмотреть сообщение
можно без AsParallel()
Можно. Но неэффективно и затратно в плане написания кода.
0
0 / 0 / 2
Регистрация: 02.01.2014
Сообщений: 240
12.02.2015, 21:54  [ТС] 5
Так можете помочь с моим кодом, я ж так делаю?
0
0 / 0 / 2
Регистрация: 02.01.2014
Сообщений: 240
14.02.2015, 22:18  [ТС] 6
Вот можете помочь в моей проге поставить второй поток на паузу и снять его?
0
447 / 305 / 47
Регистрация: 23.01.2013
Сообщений: 661
14.02.2015, 22:33 7
C#
1
Thread thr = new Thread(myThreadDelegate);
Вы в локальные переменные сохраняете ссылки, а не в поля класса.

Надо:
C#
1
thr = new Thread(myThreadDelegate);
0
Эксперт .NET
5534 / 4298 / 1217
Регистрация: 12.10.2013
Сообщений: 12,332
Записей в блоге: 2
14.02.2015, 22:47 8
Цитата Сообщение от Mansu Посмотреть сообщение
Так можете помочь с моим кодом, я ж так делаю?
Вы еще не поняли? Это НЕЭФФЕКТИВНО, понимаете? В случае использования PFX библиотека берет на себя всю работу по распараллеливанию данных и их объединению перед выдачей результата. Вам же придется делать все это самому, ручками. Если у вас есть желание тратить время на изобретение велосипеда - вперед, я предпочитаю использовать то, что уже имеется и работает так как следует.
0
Эксперт .NET
4432 / 2092 / 404
Регистрация: 27.03.2010
Сообщений: 5,657
Записей в блоге: 1
15.02.2015, 10:57 9
Цитата Сообщение от insite2012 Посмотреть сообщение
Если у вас есть желание тратить время на изобретение велосипеда - вперед, я предпочитаю использовать то, что уже имеется и работает так как следует.
А я считаю, надо уметь всё это делать руками. хотя бы раз попробовать написать, чтобы работало, а в реальных проектах использовать всем знакомые фреймворки. Для саморазвития вполне можно изобретать велосипеды, иначе только и будешь уметь кнопки на форму кидать (грубо говоря).

Добавлено через 7 минут

Не по теме:

Всегда интересовало, почему многие любят акцентировать внимание на том, что это их делегат или их поток, метод.
myDelegete, myThread.
Почему не написать, что делегат тёти моти, или деда соседа? А что, прикольно было.
Я на работе у себя видел, как человек с 8-ми летним стажем в своём проекте написать myCanvas, ещё класс логики так же начиная с my назвал. У меня это вызвало негодование. Может пора таблетки пить, чтобы нервы не портить? :)

1
Master of Orion
Эксперт .NET
6098 / 4954 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
15.02.2015, 13:21 10
insite2012, только наверное лучше ReadLines, а не ReadAllLines, всё-таки он все равно работает с IEnumerable<T>, смысла считывать всё в память нет.

Цитата Сообщение от Casper-SC Посмотреть сообщение
Всегда интересовало, почему многие любят акцентировать внимание на том, что это их делегат или их поток, метод.
myDelegete, myThread.
Почему не написать, что делегат тёти моти, или деда соседа? А что, прикольно было.
Я на работе у себя видел, как человек с 8-ми летним стажем в своём проекте написать myCanvas, ещё класс логики так же начиная с my назвал. У меня это вызвало негодование. Может пора таблетки пить, чтобы нервы не портить?
просто потому что называть переменную также, как и тип - моветон. К примеру
C#
1
Object Object {get;set;} = new Object();
Публичное поле должно с большой начинаться, поэтому нужен какой-то префикс. Для тестовых целей my весьма годен - всего 2 буквы, и всем всё ясно
0
Эксперт .NET
4432 / 2092 / 404
Регистрация: 27.03.2010
Сообщений: 5,657
Записей в блоге: 1
15.02.2015, 13:30 11
Цитата Сообщение от Psilon Посмотреть сообщение
Для тестовых целей my весьма годен - всего 2 буквы, и всем всё ясно
Ну значит с фантазией беда вообще. Не знаю. Я всё равно как-то остро на это внимание обращаю. Ну прям не нравится мне этот префикс и ничего поделать не могу и не хочу . И я не один такой ))

Добавлено через 1 минуту
Ну тупо это "Мой объект". Назови его так, чтобы было понятно в каких целях его используют. syncObject, например.
0
Master of Orion
Эксперт .NET
6098 / 4954 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
15.02.2015, 16:08 12
Casper-SC, ну вот например есть класс MyFigure со свойством Pen для отрисовки, как его назвать? DrawingPen? Так ясен пень, что он для отрисовки (ну я надеюсь)? FigurePen? Тоже бред.

В итоге префикс хреновый, "но ничего лучше не придумано"©
0
0 / 0 / 2
Регистрация: 02.01.2014
Сообщений: 240
16.02.2015, 20:30  [ТС] 13
Я вот не могу понять, как остановить поток и возобновить его потоку (что оптимально было), но проблема у меня еще в одном я не могу указать второму потоку функцию Thread 2, потому что она принимает переменную. Я вот придумал ссылаться на еще одну функцию, которая ссылается на нужную мне Thread 2 и я не могу понять, точно ли второй поток только с теми двумя функциями?
//using _CRT_SECURE_NO_WARNINGS;
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
86
87
88
89
90
91
92
93
94
using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
//using System.Threading.ManualResetEvent;
 
namespace ConsoleApplication1
{
    class Program
    {
        private static ManualResetEvent mre = new ManualResetEvent(false);
        private double suma = 0;
        private double zn = 0;
        private ThreadStart myThreadDelegate;
        private Thread thr;
        private Thread thr1;
        //public Program(){
         //zn=chys;
        //}
    //}
        public void first()
        {
          //  Console.WriteLine("Поток 2 запущен");
            Thread2(0);
        }
        public void Thread()
        {
            int i = 0;
            string[] readText = File.ReadAllLines(@"D:\test.txt");
            foreach (string s in readText)
            {
                zn = Convert.ToDouble(s);
                //Console.WriteLine("{0}",zn);
               if (zn % 17 == 0)
                {
                 //   Console.WriteLine("+");
                 //   Resume();
                    Thread2(zn);
                    zn = 0;
                }
                i++;
                //Console.Clear();
                Console.WriteLine("Оброблено {0}/1000000000", i);
              //  Console.Clear();
            }
        }
        public void Thread2(double chys)
        {
            suma += chys;
           Console.Clear();
            Console.WriteLine("Сума чисел кратних 17 ={0}", suma);
            Console.ReadLine(); 
           // Suspend();
        }
        public void Resume()
        {
            thr1.Resume();
            //mre.Set();
        }
        public void Suspend()
        {
            thr1.Abort();
           //mre.WaitOne();
        }
        public void go()
        {
            //ThreadStart myThreadDelegate = new ThreadStart(Thread);
            //Thread thr = new Thread(myThreadDelegate);
            Thread thr = new Thread(Thread);
            thr.Start();
        }
        public void go1()
        {
           // ThreadStart myThreadDelegate = new ThreadStart(first);
            //Thread thr1 = new Thread(myThreadDelegate);
            Thread thr1 = new Thread(first);
            thr1.Start();
           // Suspend();
            //thr1.Suspend();
        }
        [STAThread]
        static void Main(string[] args)
        {
            //double zn = 0;
            Program sw = new Program();
            sw.go();
            sw.go1();
            Console.ReadLine();
        }
    }
}
И все еще актуален вопрос, как остановить этот второй поток, а запустить его, когда придет число кратное 17

Добавлено через 8 минут
Я понял, что походу нормально, синхронизировал потоки, только очень прошу, помогите с паузой и возобновлением второго потока, как видите я там уже suspend, abort пробовал, но все они говорят, что я передаю null им. Я так понял, что это ругается сборщик мусора. Так, как он не может выбрать безопасную точку.

Добавлено через 2 минуты
Хотя, я думаю, что делаю через (_|_), но не могу ничего придумать лучшего
0
418 / 316 / 241
Регистрация: 29.05.2010
Сообщений: 796
Записей в блоге: 1
16.02.2015, 21:44 14
Mansu,
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
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Threading;
 
namespace ConsoleApplication5
{
    class Program
    {
 
 
      
        static void Main(string[] args)
        {
            const string fname = "numbers.txt";
            var watch = new Stopwatch();
            var random = new Random();
            using (var writer = new BinaryWriter(File.Create(fname)))
            {   
            Console.WriteLine("Пишем числа в файл:{0}",fname);
            watch.Start();
            Enumerable.Range(0,10240).Select(i=>random.Next(10,120)).ToList().ForEach(writer.Write);
            watch.Stop();
          
            Console.WriteLine("Заняло времени:{0}",watch.Elapsed);
                Console.WriteLine("Any key...");
                Console.ReadKey();
            }
            var st=new Stack<int>();
            var readerThread = new Thread(() =>
            {
                using (var reader = new BinaryReader(File.Open(fname, FileMode.Open)))
                {
                  
                    while (reader.PeekChar() != -1)
                    {
                       var number= reader.ReadInt32();
                        if (number%17 == 0)
                        {
                           st.Push(number);
                            
                        }
                       
                    }
                   
                }
            });
 
            var worker = new Thread(() =>
            {
                while (true)
                {
                    if(st.Count>0)
                    Console.Write("{0,3}\t",st.Pop());
                }
                
                
 
            }){IsBackground = true};
            readerThread.Start();
            worker.Start();
            Console.ReadKey();
 
           
        }
    }
}
0
0 / 0 / 2
Регистрация: 02.01.2014
Сообщений: 240
17.02.2015, 07:50  [ТС] 15
Так зачем мне время, я одним потоком считываю числа уже с файла и если число кратно 17, то он передаёт 2, а тот накапливает. Так вот второй поток я хочу ставить на паузу, а как я нашёл число, то возобновить, накопить и снова на паузу.
0
Эксперт .NET
5534 / 4298 / 1217
Регистрация: 12.10.2013
Сообщений: 12,332
Записей в блоге: 2
17.02.2015, 09:44 16
Цитата Сообщение от Mansu Посмотреть сообщение
тот накапливает
Как именно "накапливает"? До какого предела? Сколько он должен "накопить", чтобы вновь начать работать?
0
0 / 0 / 2
Регистрация: 02.01.2014
Сообщений: 240
17.02.2015, 21:25  [ТС] 17
Смотрите у меня в файле массив, поток thread просто считывает с файла числа и которые кратны 17, передает второму Thread 2, а тот просто накапливает, без предела, все числа кратные 17. Так вот там не очень много таких чисел и я хочу чтоб второй поток Thread 2 был на паузе, пока первый не передаст ему число, кратное 17, а потом снова его на паузу и т.д. Как это сделать?
0
17.02.2015, 21:25
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
17.02.2015, 21:25
Помогаю со студенческими работами здесь

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

Взаимодействие между членами класса
Имеем такой класс(сильно упрощенно, в одном namespace) public class A; public class B; ...

Взаимодействие между объектами в классах
Здрасте! У меня есть прога для регулирования расходов, в которой есть класс Account и класс...

Потоки и взаимодействие между ними
Всем привет! С потоками вот только начал разбираться, поэтому вопрос нубский. Каким образом...


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

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