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

Проблема с потоками

23.02.2019, 04:07. Показов 3740. Ответов 17
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Проблема заключается в том, что создается только один поток, а мне нужно 3 потока.
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
 /*Создаем экземпляр класса Task,который позволяет запускать Форму асинхронно в одном из потоков,
             что позволяет обращаться в Форме без последствий*/
             for(int i = 2; i < 5; i++)
            {
                //Task myTask = Task.Run(() =>
            //{
                /*Создаем экземпляр класса Form1(Нашей формы,в которой происходит построение графика)*/
                Form1 form = new Form1(arrx, arry, i);
                /*Вызываем функция DrawGraph,которая как раз-таки отвечает за инициализацию
                 * и построение графика*/
                //new Thread(() => form.DrawGraph(arrx, arry, i)).Start();
                Thread myThread= new Thread(() => form.DrawGraph(arrx, arry, i));
                myThread.Start();
                //myThread[i].Name = "Поток полинома " + i.ToString() + " степени";
                Console.WriteLine("Поток №{0}",Thread.CurrentThread.GetHashCode()); 
                //Console.WriteLine(myThread[i].Name); 
                //Thread myThread= new Thread(new ThreadStart (form.DrawGraph));
                //myThread.Name = "Поток полинома" + i.ToString()+ "степени ";
                //myThread.Start();
                //form.DrawGraph(arrx, arry,n);
                /*Показываем форму,в которой уже нарисовался график функции*/
                form.ShowDialog();
               //hread.Sleep(500);
            //});
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
23.02.2019, 04:07
Ответы с готовыми решениями:

Проблема с потоками.
Пробую написать IRC бота на шарпе. В отдельном процессе запускается пинг сервера метод PingServer(). Так же запускается таймер,...

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

проблема с потоками
Ребят при написании программы появилась проблема, опишу вкратце. пишу интерфейс WTL шаблонами. В MainWindow класса есть метод обработки...

17
Фрилансер
805 / 312 / 148
Регистрация: 13.02.2019
Сообщений: 1,071
23.02.2019, 08:12
Цитата Сообщение от artur31154 Посмотреть сообщение
создается только один поток
на основании чего сделан такой вывод?
0
0 / 0 / 0
Регистрация: 09.10.2018
Сообщений: 115
23.02.2019, 10:49  [ТС]
asn31337, на основании того, что вывожу номер текущего потока, а он всегда равен одному
0
Фрилансер
805 / 312 / 148
Регистрация: 13.02.2019
Сообщений: 1,071
23.02.2019, 11:28
Цитата Сообщение от artur31154 Посмотреть сообщение
вывожу номер текущего потока, а он всегда равен одному
Неверная у Вас логика))) Дело в том, что у Вас в цикле открывается форма в режиме диалога. Пока форма не будет закрыта, новая итерация не начнется. Тем временем поток завершает свою работу и на новой итерации стартует с тем же номером. Попробуйте открывать форму не модально. По идее, должно открыться 3 формы, каждая из которых будет отработана своим потоком.
0
0 / 0 / 0
Регистрация: 09.10.2018
Сообщений: 115
23.02.2019, 11:32  [ТС]
asn31337, То есть, вы предлагаете использовать Task.run?Просто, если использовать его, то работает все в отдельных потоках, но мне казалось, что есть другие способы
0
Фрилансер
805 / 312 / 148
Регистрация: 13.02.2019
Сообщений: 1,071
23.02.2019, 11:34
Цитата Сообщение от artur31154 Посмотреть сообщение
То есть, вы предлагаете использовать Task.run?
Нет. Я предлагаю вместо form.ShowDialog(); использовать form.Show();
0
0 / 0 / 0
Регистрация: 09.10.2018
Сообщений: 115
23.02.2019, 11:37  [ТС]
asn31337, Если так, то все также один поток все обрабатывает
0
Фрилансер
805 / 312 / 148
Регистрация: 13.02.2019
Сообщений: 1,071
23.02.2019, 11:43
Цитата Сообщение от artur31154 Посмотреть сообщение
также один поток все обрабатывает
Значит, просто работа потока занимает очень мало времени и к моменту второй итерации поток уже отрабатывает (попробуйте искусственно затормозить работу метода, который выполняется в потоке, например, Thread.Sleep).
А в чем принципиальность именно 3-х потоков?
0
0 / 0 / 0
Регистрация: 09.10.2018
Сообщений: 115
23.02.2019, 11:46  [ТС]
asn31337, Мне нужно, чтобы каждый из потоков обрабатывал свой полином n-ой степени, то есть 2-ой поток обрабатывает вторую степень и так далее.Мне нужно как-то синхронизировать их работу с помощью ManualResetEvent или AutoResetEvent

Добавлено через 57 секунд
asn31337, И еще, я заметил, что если использовать просто Show, то форма не может загрузится, просто белое окно.Так что, это не выход :C
0
Фрилансер
805 / 312 / 148
Регистрация: 13.02.2019
Сообщений: 1,071
23.02.2019, 11:57
Лучший ответ Сообщение было отмечено artur31154 как решение

Решение

artur31154, чет я сразу то не обратил внимание... Вы номер выводите всегда для основного потока))) Чтобы вывести номер запущенного перенесите строку
C#
1
Console.WriteLine("Поток №{0}",Thread.CurrentThread.GetHashCode());
в тело потока.

Цитата Сообщение от artur31154 Посмотреть сообщение
если использовать просто Show, то форма не может загрузится, просто белое окно
только что проверил, все норм работает. если не грузится форма, значит где то в коде косяк.
1
0 / 0 / 0
Регистрация: 09.10.2018
Сообщений: 115
23.02.2019, 12:02  [ТС]
asn31337, Так, больше Вам спасибо!.И еще, можно как-то синхронизировать эти потоки с помощью autoResetEvent или ManualResetEvent?
0
Фрилансер
805 / 312 / 148
Регистрация: 13.02.2019
Сообщений: 1,071
23.02.2019, 12:18
Лучший ответ Сообщение было отмечено artur31154 как решение

Решение

Цитата Сообщение от artur31154 Посмотреть сообщение
можно как-то синхронизировать эти потоки с помощью autoResetEvent или ManualResetEvent?
А в чем должна заключаться синхронизация? Эвенты просто имеют 2 состояния - сигнальное и несигнальное. Т.е. можно, к примеру, послать сигнал и поток будет приостановлен до получения сигнала. Под синхронизацией обычно подразумевается использование несколькими потоками одной и той же переменной. Если все потоки только читают ее, то синхронизация вообще не нужна. Если же возможно изменение значения переменной во время работы потока, то используют lock, mutex или семафоры.
1
0 / 0 / 0
Регистрация: 09.10.2018
Сообщений: 115
23.02.2019, 12:51  [ТС]
asn31337, asn31337, чтобы каждый поток выполнялся по-очереди строго

Добавлено через 26 минут
asn31337, В общем, с синхронизацией потоков с помощью события я вроде бы разобрался.Теперь проблема с Show, она отображается белое окно, которое даже закрыть нельзя с помощью крестика.Вот код:
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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Threading;
using ZedGraph;
 
namespace Лаба2._1
{
    /*Форма Form1 для построения графиков,которая наследуется от класса Form,в котором описаны начальные инструкции*/
    public partial class Form1 : Form
    {
        static object locker = new object();
        static EventWaitHandle waitHandle = new AutoResetEvent(false);
        private double[] arrx;
        private double[] arry;
        private int i;
        /*Конструктор класса Form1*/
        public Form1(double[] arrx, double[] arry, int i)
        { 
                this.arrx = arrx;
                this.arry = arry;
            this.i = i;
        InitializeComponent();
        }
        public Form1()
        {
 
        }
        /*функция вычисления интерполяционного полинома лагранжа,которая принимает в аргументы значение x
         *и два одномерных массива x,y типа double*/
        public double Lagrange(double x0, double[] x, double[] y)
        {
            /*Объявление переменной polinom типа double и инициализация нулем*/
            double polinom = 0;
            /*Цикл вычисления интерполяционного полинома Лагранжа*/
            for (int j = 0; j < x.Length; j++)
            {
                /*Объявление переменной p типа double и инициализация единицей*/
                double p = 1;
                /*Цикл вычисление базисных полиномов*/
                for (int i = 0; i <x.Length; i++)
                    if (j != i)
                    {
                        /*Вычисление базисных полиномов по формуле Лагранжа*/
                        p *=  (x0 - x[i]) / (x[j] - x[i]);
                    }
                /*Вычисление интерполяционного полинома Лагранжа*/
                polinom += y[j] * p;
            }
            /*Возвращение значения polinom*/
            return polinom;
        }
        /*Функция,которая добавляет точки на график и рисует график функции,принимающая два массива x,y типа double*/
        public void DrawGraph(double[] x, double[] y,int n,EventWaitHandle waitHandle)
        {
            
            Console.WriteLine("Поток №{0}", Thread.CurrentThread.GetHashCode());
            /* Получим панель для рисования*/
            GraphPane pane = zedGraphControl1.GraphPane;
            pane.Title.Text = "Интерполяционный полином Лагранжа";            
            /*Предварительно очищаем панель*/
            pane.CurveList.Clear();
            /*Создадим список точек*/
            PointPairList list_1 = new PointPairList();
            PointPairList list_2 = new PointPairList();
            /*Заполняем список точек*/
            for (int i = 0; i < x.Length; i++)
            {
                list_1.Add(x[i], y[i]);
            }
 
            /*Интерполируем несколько точек между узлами*/
            for (int i = 0; i < x.Length-1 ; i++)
            {
                for (int j = 0; j < n; j++)
                {
                    /*Объявляем переменную local типа double и присваиваем выражение,по которому вычисляется будущий x*/
                    double local = x[i] + j * (x[i + 1] - x[i])/n;
                    /*Заполнение списка точек,кроме последней точки,
                     *вызовом функции вычисления интерполяционного полинома Лагранжа*/
                    list_2.Add(local, Lagrange(local, x, y));
                }
            }
            /*Добавление последней точки в список*/
            list_2.Add(x[x.Length - 1], y[y.Length - 1]);
            /*Объявляем два экземпляра класса LineItem.Рисуем линии по точкам*/
            Console.WriteLine("Рисую график, пожалуйста, подождите");
            LineItem myCurve1 = pane.AddCurve("Исходная функция", list_1, Color.Purple, SymbolType.Diamond);
            LineItem myCurve2 = pane.AddCurve("Интерполяционный полином", list_2, Color.Red, SymbolType.None);
            Console.WriteLine("График готов!");
            /* По оси Y установим автоматический подбор масштаба*/
            pane.YAxis.Scale.MinAuto = true;
            pane.YAxis.Scale.MaxAuto = true;
            /*Установим значение параметра IsBoundedRanges как true.
              Это означает, что при автоматическом подборе масштаба 
              нужно учитывать только видимый интервал графика*/
            pane.IsBoundedRanges = true;
            /*Обновляем данные об осях*/
            pane.AxisChange();
            /*Обновляем график*/
            zedGraphControl1.Invalidate();
          waitHandle.WaitOne();
            
            
        }
        /*private void zedGraphControl1_Load(object sender, EventArgs e)
        {
 
        }*/
 
        /*private void zedGraphControl1_Load(object sender, EventArgs e)
        {
 
        }*/
    }
 
}
0
Фрилансер
805 / 312 / 148
Регистрация: 13.02.2019
Сообщений: 1,071
23.02.2019, 12:56
Цитата Сообщение от artur31154 Посмотреть сообщение
чтобы каждый поток выполнялся по-очереди строго
А зачем тогда вообще нужно несколько потоков, если они все равно должны работать по-очереди?
Ну, если очень хочется... Тогда примерно так должно быть:
1. Надо создать 2 глобальных переменных типа ManualResetEvent (обе в несигнальном состоянии).
2. Создаем и запускаем все 3 потока, но во 2-м и 3-м первой строкой ждем сигнального состояния ManualResetEvent.
3. по завершении 1-го потока устанавливаем 1-ю переменную в сигнальное состояние - начинает выполняться второй поток
4. по завершении 2-го потока устанавливаем 2-ю переменную в сигнальное состояние - выполняется 3-й поток.

Это очень примерно, так сказать набросок...
0
0 / 0 / 0
Регистрация: 09.10.2018
Сообщений: 115
23.02.2019, 13:01  [ТС]
asn31337, я это смог реализовать, теперь проблема в форме, так как мне нужно, чтобы сразу отобразились все формы n-ой степени поочереди, поэтому для этого целесобразно использовать Show(), но он почему-то не работает у меня, понять не могу.А ShowDialog не подходит, так как он блокирует все остальные формы и они не выводятся, пока не закроешь эту форму
0
Фрилансер
805 / 312 / 148
Регистрация: 13.02.2019
Сообщений: 1,071
23.02.2019, 13:17
Цитата Сообщение от artur31154 Посмотреть сообщение
C#
1
static EventWaitHandle waitHandle = new AutoResetEvent(false);
переменная находится в несигнальном состоянии и ее значение нигде не меняется. получается код доходит до строки
Цитата Сообщение от artur31154 Посмотреть сообщение
C#
1
waitHandle.WaitOne();
и "зависает" в ожидании сигнала...

Добавлено через 1 минуту
Возможно, дело не только в этом, но это тоже косяк)))

Добавлено через 9 минут
И, кстати, не очень понял... Form1 - это единственная форма или еще есть? Приложение как запускается?
0
0 / 0 / 0
Регистрация: 09.10.2018
Сообщений: 115
23.02.2019, 14:14  [ТС]
asn31337, да, это единственная форма,а запускается она через консольное приложение в методе main

Добавлено через 52 минуты
asn31337, А зачем тогда вообще нужно несколько потоков, если они все равно должны работать по-очереди?
Ну, если очень хочется... Тогда примерно так должно быть:
1. Надо создать 2 глобальных переменных типа ManualResetEvent (обе в несигнальном состоянии).
2. Создаем и запускаем все 3 потока, но во 2-м и 3-м первой строкой ждем сигнального состояния ManualResetEvent.
3. по завершении 1-го потока устанавливаем 1-ю переменную в сигнальное состояние - начинает выполняться второй поток
4. по завершении 2-го потока устанавливаем 2-ю переменную в сигнальное состояние - выполняется 3-й поток.

Это очень примерно, так сказать набросок...

А можете подробнее описать?
0
Фрилансер
805 / 312 / 148
Регистрация: 13.02.2019
Сообщений: 1,071
23.02.2019, 20:06
Лучший ответ Сообщение было отмечено artur31154 как решение

Решение

Цитата Сообщение от artur31154 Посмотреть сообщение
А можете подробнее описать?
Навскидку:
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
        static ManualResetEvent start2 = new ManualResetEvent(false);
        static ManualResetEvent start3 = new ManualResetEvent(false);
        
        static void Main(string[] args)
        {
            for(int i = 0; i < 3; i++)
            {
                Thread t = new Thread((object obj) =>
                {
                    int a = (int)obj;
 
                    if (a == 1)
                    {
                        start2.WaitOne();
                    }
                    else if (a == 2)
                    {
                        start3.WaitOne();
                    }
 
                    Console.WriteLine($"Thread {a} started");
                    Thread.Sleep(1000);
                    Console.WriteLine($"Thread {a} stopped");
 
                    if (a == 0)
                        start2.Set();
                    else if (a == 1)
                        start3.Set();
                });
                t.Start(i);
            }
            Console.ReadKey();
        }
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
23.02.2019, 20:06
Помогаю со студенческими работами здесь

Проблема с потоками
Здравствуйте. Подскажите пожалуйста. Проблема такая. Программа из этого примера http://www.realcoding.net/article/view/101. При...

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

Проблема с потоками (файлы)
В коде программы необходимо несколько раз открывать один и тот же файл. Проблема в том, когда закрываешь поток для сохранения данных в...

Проблема при работе с потоками
Помогите решить тупую проблему! Есть массив строк: String MassStr = new String{'one', 'two', 'three'}; Теперь я хочу чтобы...

Проблема с широкими потоками(wofstream)
Вот такое дело. Код: w_char* xmlRezult;//здесь хранится имя файла wstringstream* outputStream;//здесь хранится конечный текст...


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

Или воспользуйтесь поиском по форуму:
18
Ответ Создать тему
Новые блоги и статьи
сукцессия микоризы: основная теория в виде двух уравнений.
anaschu 11.01.2026
https:/ / rutube. ru/ video/ 7a537f578d808e67a3c6fd818a44a5c4/
WordPad для Windows 11
Jel 10.01.2026
WordPad для Windows 11 — это приложение, которое восстанавливает классический текстовый редактор WordPad в операционной системе Windows 11. После того как Microsoft исключила WordPad из. . .
Classic Notepad for Windows 11
Jel 10.01.2026
Old Classic Notepad for Windows 11 Приложение для Windows 11, позволяющее пользователям вернуть классическую версию текстового редактора «Блокнот» из Windows 10. Программа предоставляет более. . .
Почему дизайн решает?
Neotwalker 09.01.2026
В современном мире, где конкуренция за внимание потребителя достигла пика, дизайн становится мощным инструментом для успеха бренда. Это не просто красивый внешний вид продукта или сайта — это. . .
Модель микоризы: классовый агентный подход 3
anaschu 06.01.2026
aa0a7f55b50dd51c5ec569d2d10c54f6/ O1rJuneU_ls https:/ / vkvideo. ru/ video-115721503_456239114
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR
ФедосеевПавел 06.01.2026
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR ВВЕДЕНИЕ Введу сокращения: аналоговый ПИД — ПИД регулятор с управляющим выходом в виде числа в диапазоне от 0% до. . .
Модель микоризы: классовый агентный подход 2
anaschu 06.01.2026
репозиторий https:/ / github. com/ shumilovas/ fungi ветка по-частям. коммит Create переделка под биомассу. txt вход sc, но sm считается внутри мицелия. кстати, обьем тоже должен там считаться. . . .
Расчёт токов в цепи постоянного тока
igorrr37 05.01.2026
/ * Дана цепь постоянного тока с сопротивлениями и источниками (напряжения, ЭДС и тока). Найти токи и напряжения во всех элементах. Программа составляет систему уравнений по 1 и 2 законам Кирхгофа и. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru