Форум программистов, компьютерный форум, киберфорум
C# .NET
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.76/21: Рейтинг темы: голосов - 21, средняя оценка - 4.76
8 / 8 / 1
Регистрация: 17.01.2010
Сообщений: 172
1

Как создать три потока с одним методом

26.02.2012, 18:20. Показов 4366. Ответов 19
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Не могу создать 3 потока и запустить их. Суть проги такая. В ТекстБокс1 и ТекстБокс2 вводятся данные, если эти данные числа, то они суммируются, если не числа, то они соеденяются. Это я оформил в виде метода MyMetod. Мне надо чтобы по нажатию кнопки создалось 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
25
26
27
28
29
30
namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        
        void MyMetod(System.Windows.Forms.TextBox tb) // мой метод. работает.
        {
            int n;
            if (int.TryParse(textBox1.Text, out n) & int.TryParse(textBox2.Text, out n))
            {
                tb.Text = Convert.ToString(Convert.ToInt32(textBox1.Text) + Convert.ToInt32(textBox2.Text));
            }
            else
            {
                tb.Text = textBox1.Text + textBox2.Text;
            }
        }
 
        private void button1_Click(object sender, EventArgs e)
        {
            Thread th_1 = new Thread(MyMetod(textBox3)); // здесь выходит ошибка
            Thread th_2 = new Thread(MyMetod(textBox4)); // здесь выходит ошибка
            Thread th_3 = new Thread(MyMetod(textBox5)); // здесь выходит ошибка
        } 
    }
}
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
26.02.2012, 18:20
Ответы с готовыми решениями:

Как использовать объект, созданный одним методом, другим методом?
Написал класс: class _MainMenu { private string _allOpenFileNameAndPath;//Массив...

Как сделать INSERT в три таблицы одним махом (соединены 1 к 1)
Народ, очень нужна помощь. У меня 3 таблицы, и каждая соединена 1к1. Табл1-Табл2 один к одному, и...

Как остановить три потока по очереди?
Как остановить три потока по очереди. У меня в трех textBox генерируются числа в трех потоках, и...

Работа с сокетами, как сделать весь цикл While одним методом
Вот весь код:byte sendText; string resvStr = string.Empty; int ind = -1;...

19
Эксперт .NET
17685 / 12871 / 3365
Регистрация: 17.09.2011
Сообщений: 21,136
26.02.2012, 18:40 2
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
void MyMetod(object obj) // мой метод. работает.
        {
            var tb = obj as System.Windows.Forms.TextBox;
            int n;
            if (int.TryParse(textBox1.Text, out n) & int.TryParse(textBox2.Text, out n))
            {
                tb.Text = Convert.ToString(Convert.ToInt32(textBox1.Text) + Convert.ToInt32(textBox2.Text));
            }
            else
            {
                tb.Text = textBox1.Text + textBox2.Text;
            }
        }
 
        private void button1_Click(object sender, EventArgs e)
        {
            Thread th_1 = new Thread(MyMetod);
            Thread th_2 = new Thread(MyMetod);
            Thread th_3 = new Thread(MyMetod);
 
            th_1.Start(textBox3);
            th_2.Start(textBox4);
            th_3.Start(textBox5);
        }
2
8 / 8 / 1
Регистрация: 17.01.2010
Сообщений: 172
26.02.2012, 19:23  [ТС] 3
Спасибо за код. Попробую.

Добавлено через 2 минуты
Цитата Сообщение от kolorotur Посмотреть сообщение
tb.Text = textBox1.Text + textBox2.Text;
Не сработало. На этой строке выходит ошибка " Недопустимая операция в нескольких потоках: попытка доступа к элементу управления 'textBox4' не из того потока, в котором он был создан."
0
Заблокирован
26.02.2012, 19:39 4
По поиску на форуме в этом разделе или на раздел выше по ключевым словам "Invoke" или "delegate" посмотрите.
Для работы потоков с контролами формы есть ограничения, которые нужно обходить.
0
Эксперт .NET
4432 / 2092 / 404
Регистрация: 27.03.2010
Сообщений: 5,657
Записей в блоге: 1
26.02.2012, 19:42 5
Цитата Сообщение от Marat-209 Посмотреть сообщение
Недопустимая операция в нескольких потоках: попытка доступа к элементу управления 'textBox4' не из того потока, в котором он был создан."
Смотри тут: Создать label на форме из другого потока и работать с ним (метод UpdateInformation)
0
8 / 8 / 1
Регистрация: 17.01.2010
Сообщений: 172
27.02.2012, 08:48  [ТС] 6
Я не силен в делегатах. Может кто поможет.
0
Exerion
27.02.2012, 09:45
  #7

Не по теме:

Было бы неплохо почитать на форуме разжёванную статью про делегаты. Я уже полгода сижу на шарпе, но пока с делегатами не дружу. Чисто человеческий смысл их не понимаю: что это, зачем это, как использовать это и т.д. Может, опыта мало для понимания... Статьи на msdn (и не только на msdn) простого объяснения не дают, но благо у меня пока не возникало ситуации, в которой без делегатов не обойтись. Но ведь они очень распространены и используются довольно часто.
Кто бы по-простому объяснил.

0
Эксперт .NET
17685 / 12871 / 3365
Регистрация: 17.09.2011
Сообщений: 21,136
27.02.2012, 09:51 8
Exerion, делегат - это ссылка на метод. Больше там и объяснять-то нечего.
Используется, соответственно, там, где надо передать ссылку на метод в другой метод/класс, который потом ее будет использовать.
1
[Bicycle Reinventor]
332 / 270 / 109
Регистрация: 19.10.2011
Сообщений: 668
Записей в блоге: 2
27.02.2012, 10:30 9
kolorotur, тогда в чём основная суть? Вопросов только больше становится.
Например, если сделать метод модификатором public, к нему и без делегатов доступ будет.

1. В каких ситуациях вообще возникает необходимость "передавать ссылку на" ?
2. Можно ли с помощью делегата обратиться к методу определённого не static класса, без объявления его экземпляра?
3. Можно ли с помощью делегата взаимодействовать с одним и тем же com-портом из нескольких потоков одновременно?

и в целом 4. В чём основное преимущество делегатов; когда их принято использовать?
0
Эксперт .NET
17685 / 12871 / 3365
Регистрация: 17.09.2011
Сообщений: 21,136
27.02.2012, 10:50 10
Основная суть в том, чтобы сторонней системе предложить свою реализацию определенной части задачи. А-ля плагин.

Цитата Сообщение от Exerion Посмотреть сообщение
1. В каких ситуациях вообще возникает необходимость "передавать ссылку на" ?
Вы LINQ'ом, к примеру, пользуетесь? Вот там повсюду делегаты требуются, их еще зачастую через лямбда-выражение пишут.
Возьмем, например, метод-расширение Select. Вся его суть заключается в том, чтобы взять из источника каждый элемент и преобразовать его в другой тип. Собственно, переданный в метод Select делегат и отвечает за преобразование. Реализация этого метода выглядит так:
C#
1
2
3
4
5
public static IEnumerable<TResult> Select(this IEnumerable<TSource> source, Func<TSource, TResult> selector)
{
   foreach (TSource element in source)
      yield return selector(element);
}
Func<TSource, TResult> - это делегат на метод, принимающий параметром экземпляр типа TSource и возвращающий экземпляр типа TResult

То есть для каждого элемента в источнике запускается некий метод, который принимает на входе тип элемента, содержащегося в источнике, и возвращает экземпляр другого типа.
Что именно происходит при вызове делегата selector определяет пользователь, давая ссылку на нужный ему метод.
C#
1
2
3
string[] strings = { "1", "2", "3", "4" };
int[] ints = strings.Select(int.Parse).ToArray(); // Передается ссылка на метод int.Parse, в результате каждый элемент массива strings будет преобразован в целочисленный тип
double[] doubles = strings.Select(double.Parse); // ... или в вещественный тип
Или другой пример. Вы события обрабатываете в коде? Вот событие (event) - это тоже специализированный делегат. Когда вы подписываетесь на событие (button1.Click += button1_Click), вы передаете ссылку на метод, который должен запускаться при его срабатывании.

Цитата Сообщение от Exerion Посмотреть сообщение
2. Можно ли с помощью делегата обратиться к методу определённого не static класса, без объявления его экземпляра?
Нет, так как не-статический метод является членом экземпляра класса. Соответственно, без наличия экземпляра этого метода не существует.

Цитата Сообщение от Exerion Посмотреть сообщение
3. Можно ли с помощью делегата взаимодействовать с одним и тем же com-портом из нескольких потоков одновременно?
Не совсем понял вопрос.
Если в вашей системе имеется возможность вызывать некий метод из нескольких потоков одновременно для взаимодействия с ком-портом без обрушения программы, то можно.

Цитата Сообщение от Exerion Посмотреть сообщение
4. В чём основное преимущество делегатов; когда их принято использовать?
Когда надо вызвать метод, реализация которого может меняться в зависимости от текущих требований.
2
[Bicycle Reinventor]
332 / 270 / 109
Регистрация: 19.10.2011
Сообщений: 668
Записей в блоге: 2
27.02.2012, 10:56 11
Цитата Сообщение от kolorotur Посмотреть сообщение
Когда надо вызвать метод, реализация которого может меняться в зависимости от текущих требований.
Вооот, вот что мне хотелось услышать. Теперь более понятен смысл, спасибо.
Пойду перечитаю статейки msdn'овские.
0
8 / 8 / 1
Регистрация: 17.01.2010
Сообщений: 172
27.02.2012, 19:15  [ТС] 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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
 
        void MyMetod(object obj) // мой метод. работает.
        {
 
            var tb = obj as System.Windows.Forms.TextBox;
            int n;
 
            if (int.TryParse(textBox1.Text, out n) & int.TryParse(textBox2.Text, out n))
            {
                tb.BeginInvoke(new Action(delegate
                    {
                        tb.Text = Convert.ToString(Convert.ToInt32(textBox1.Text) + Convert.ToInt32(textBox2.Text));
                    }));
            }
            else
            {
                tb.BeginInvoke(new Action(delegate
                {
                    tb.Text = textBox1.Text + textBox2.Text;
                }));
            }
        }
 
        private void button1_Click(object sender, EventArgs e)
        {
            Thread th_1 = new Thread(MyMetod);
            Thread th_2 = new Thread(MyMetod);
            Thread th_3 = new Thread(MyMetod);
 
            th_1.Start(textBox3);
            th_2.Start(textBox4);
            th_3.Start(textBox5);
        } 
    }
}
0
Эксперт .NET
4432 / 2092 / 404
Регистрация: 27.03.2010
Сообщений: 5,657
Записей в блоге: 1
27.02.2012, 19:31 13
Я бы как-то так сделал:
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
using System;
using System.Threading;
using System.Windows.Forms;
 
namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
 
        void MyMetod(object obj) 
        {
            var tb = (System.Windows.Forms.TextBox)obj;
            int number1;
            int number2;
 
            if (int.TryParse(textBox1.Text, out number1) && int.TryParse(textBox2.Text, out number2)) //&&
            {
                tb.BeginInvoke((Action)delegate
                {
                    tb.Text = (number1 + number2).ToString();
                });
            }
            else
            {
                tb.BeginInvoke((Action)delegate
                {
                    tb.Text = textBox1.Text + textBox2.Text;
                });
            }
        }
 
        private void button1_Click(object sender, EventArgs e)
        {
            Thread th_1 = new Thread(MyMetod);
            Thread th_2 = new Thread(MyMetod);
            Thread th_3 = new Thread(MyMetod);
 
            th_1.Start(textBox3);
            th_2.Start(textBox4);
            th_3.Start(textBox5);
        }
    }
}
А насчёт китайца, ты похоже про содержимое button1_Click? Для конкретного примера и так сойдёт. А если у тебя много потоков делающих одно и тоже, то пихай в массив например.
0
8 / 8 / 1
Регистрация: 17.01.2010
Сообщений: 172
27.02.2012, 22:15  [ТС] 14
Последний вопросик. надеюсь последний. Чем отличается
t
C#
1
2
3
4
b.BeginInvoke(new Action(delegate
                {
                    tb.Text = textBox1.Text + textBox2.Text;
                }));
от

C#
1
2
3
4
tb.BeginInvoke((Action)delegate
                {
                    tb.Text = textBox1.Text + textBox2.Text;
                });
Добавлено через 2 часа 20 минут
Переписал программу. добавив приоритеты потокам и счетчик времени выполнения потока. Снова ошибка в
C#
1
2
3
Thread th_1 = new Thread(MyMetod);
            Thread th_2 = new Thread(MyMetod);
            Thread th_3 = new Thread(MyMetod);
Пишет Аргумент "1": преобразование типа из "группа методов" в "System.Threading.ThreadStart" невозможно. и
Наиболее подходящий перегруженный метод для "System.Threading.Thread.Thread(System.Threading.ParameterizedThreadStart)" имеет несколько недопустимых аргументов

Вот код программы
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
namespace WindowsFormsApplication1
{
    
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
 
        void MyMetod(object obj, object obj2 ) 
        {
            Stopwatch stopWatch = new Stopwatch();
            stopWatch.Start();
 
            var tb = obj as System.Windows.Forms.TextBox;
            var lb = obj2 as System.Windows.Forms.Label;
 
            int n;
            if (int.TryParse(textBox1.Text, out n) & int.TryParse(textBox2.Text, out n))
            {
                tb.BeginInvoke(new Action(delegate
                    {
                        tb.Text = Convert.ToString(Convert.ToInt32(textBox1.Text) + Convert.ToInt32(textBox2.Text));
                    }));
            }
            else
            {
                tb.BeginInvoke(new Action(delegate
                {
                    tb.Text = textBox1.Text + textBox2.Text;
                }));
            }
            for (int i = 0; i < 10000000; i++)
            {
                //цикл для задержки времени
            }
            stopWatch.Stop();
            TimeSpan ts = stopWatch.Elapsed;
            string elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}", ts.Hours, ts.Minutes, ts.Seconds, ts.Milliseconds);
            lb.BeginInvoke(new Action(delegate
                {
                    lb.Text = Convert.ToString("Времени затрачено " + elapsedTime);
                }));
        }
 
        private void button1_Click(object sender, EventArgs e)
        {
            Thread th_1 = new Thread(MyMetod);
            Thread th_2 = new Thread(MyMetod);
            Thread th_3 = new Thread(MyMetod);
 
            th_1.Priority = ThreadPriority.Lowest;
            th_2.Priority = ThreadPriority.Highest;
            th_3.Priority = ThreadPriority.Normal;
 
            th_1.Start(textBox3);
            th_2.Start(textBox4);
            th_3.Start(textBox5);
        } 
    }
}
Само задание на программу
Разработать программу, осуществляющую ввод двух строк, введенных пользователем. Далее, если обе строки хранят целые числа со знаком, то на экран выводится сумма чисел, в противном случае – конкатенация двух введенных строк. Проверку на соответствие строки целому числу, вычисление суммы чисел и конкатенации строк оформить как три разных функции
потока (с приоритетами, соответственно, THREAD_PRIORITY_ABOVE_NORMAL, HREAD_PRIORITY_LOWEST и THREAD_PRIORITY_IDLE). Ввод строк осуществляется до запуска всех потоков, а вывод результатов – после их завершения. Также выводятся значения времени работы каждого потока.
0
Эксперт .NET
4432 / 2092 / 404
Регистрация: 27.03.2010
Сообщений: 5,657
Записей в блоге: 1
27.02.2012, 22:40 15
Ты всерьёз считаешь что это хороший способ?
C#
1
2
3
4
5
6
7
8
            int n;
            if (int.TryParse(textBox1.Text, out n) & int.TryParse(textBox2.Text, out n))
            {
                tb.BeginInvoke(new Action(delegate
                    {
                        tb.Text = Convert.ToString(Convert.ToInt32(textBox1.Text) + Convert.ToInt32(textBox2.Text));
                    }));
            }
Ты тут выполняешь лишние действия.

Не по теме:

Заметил практически всегда, после того как покажешь вариант получше (если он конечно реально лучше), его всё равно не используют.



Проблема в том, что у тебя в методе 2 параметра. Короче посмотри как объявлен делегат ParameterizedThreadStart, у него 1 параметр типа object, а ты ему "суёшь" метод с 2-мя параметрами.
0
8 / 8 / 1
Регистрация: 17.01.2010
Сообщений: 172
27.02.2012, 22:52  [ТС] 16
Цитата Сообщение от Casper-SC Посмотреть сообщение
Ты тут выполняешь лишние действия.
Здесь смысл задачи не в этом, а именно создать 3 потока с разными приорететами и посчитать затраченое время на выполнение каждого потока.

Цитата Сообщение от Casper-SC Посмотреть сообщение
Проблема в том, что у тебя в методе 2 параметра.
Разве в методе не может быть 2 параметра?

Добавлено через 3 минуты
Цитата Сообщение от Casper-SC Посмотреть сообщение
Ты всерьёз считаешь что это хороший способ?
C#
1
2
3
4
5
6
7
8
            int n;
            if (int.TryParse(textBox1.Text, out n) & int.TryParse(textBox2.Text, out n))
            {
                tb.BeginInvoke(new Action(delegate
                    {
                        tb.Text = Convert.ToString(Convert.ToInt32(textBox1.Text) + Convert.ToInt32(textBox2.Text));
                    }));
            }
Ты тут выполняешь лишние действия.

Не по теме:

Заметил практически всегда, после того как покажешь вариант получше (если он конечно реально лучше), его всё равно не используют.



Проблема в том, что у тебя в методе 2 параметра. Короче посмотри как объявлен делегат ParameterizedThreadStart, у него 1 параметр типа object, а ты ему "суёшь" метод с 2-мя параметрами.
Может я не понял пример, но кажется как то глупо создавать второй метод, когда можно использовать один.
0
Эксперт .NET
4432 / 2092 / 404
Регистрация: 27.03.2010
Сообщений: 5,657
Записей в блоге: 1
27.02.2012, 22:55 17
Цитата Сообщение от Marat-209 Посмотреть сообщение
Здесь смысл задачи не в этом
Да какая разница, как мне кажется всегда надо стараться сделать лучше. Хотя, если просто лишьбы задачу решить.

Цитата Сообщение от Marat-209 Посмотреть сообщение
Разве в методе не может быть 2 параметра?
Вообще дочитал что я дальше написал?

Добавлено через 1 минуту
Цитата Сообщение от Marat-209 Посмотреть сообщение
Может я не понял пример, но кажется как то глупо создавать второй метод, когда можно использовать один.
Да я про свой вариант твоего метода: Как создать три потока с одним методом
0
8 / 8 / 1
Регистрация: 17.01.2010
Сообщений: 172
28.02.2012, 09:33  [ТС] 18
Так как мне сделать мой метод с двумя параметрами? Судя по этой статье http://msdn.microsoft.com/ru-r... 53s52.aspx мне надо создать второй метод?
0
6 / 6 / 0
Регистрация: 28.02.2012
Сообщений: 14
28.02.2012, 10:41 19
Попробуй сделать так:
C#
1
2
3
4
5
6
7
8
9
10
void MyMetod(object obj) 
        {
            Stopwatch stopWatch = new Stopwatch();
            stopWatch.Start();
 
            Object[] Temp=(Object[]) obj;
            var tb = Temp[0] as System.Windows.Forms.TextBox;
            var lb = Temp[1] as System.Windows.Forms.Label;
            ...
         }
Передавай так:
C#
1
         th_1.Start(new Object[]{textBox,label});
1
8 / 8 / 1
Регистрация: 17.01.2010
Сообщений: 172
28.02.2012, 20:08  [ТС] 20
Домой приду попробую.

Добавлено через 18 секунд
Домой приду домой попробую.

Добавлено через 9 часов 7 минут
Спасибо всем за помощь. Программа работает как надо. Замечания по оптимизации кода форумчанина Casper-SC были учтены.
0
28.02.2012, 20:08
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
28.02.2012, 20:08
Помогаю со студенческими работами здесь

Как передать значение возвращёное одним методом в другой метод
Хочу передать что вычислил метод Stroca() в мeтод TE(); как это сделать? Где можно было бы...

Как можно обрабатывать разные типы одним и тем же методом кроме перегрузки
Здраствуйте, интересует такой вопрос. Есть классы A,B,C. Класс С принимает внутри себя классы A...

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

Как после обработки потока запустить его с новым методом?
Как после обработки потока запустить его с новым методом? Возможно ли это на С/С++?


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

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