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

Синхронизация потоков

06.05.2013, 13:01. Показов 3565. Ответов 36
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Подскажите как сделать так, чтоб потоки выполнялись по порядку

вот такой простой код

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
using System;
using System.Diagnostics;
using System.Threading;
using System.Windows;
 
namespace WpfApplication1
{
    /// <summary>
    /// Логика взаимодействия для MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }
 
        private Thread t;
        private int i = 0;
        readonly object _syncLock = new object();
 
        private void button1_Click(object sender, RoutedEventArgs e)
        {
            i++;
            t = new Thread(Sms);
            t.Start(i);
        }
        private void Sms(object iii)
        {
            lock (_syncLock)
            {
                int ii = Convert.ToInt32(iii);
 
                Debug.WriteLine("Отправка " + ii);
                Thread.Sleep(3000);
                Debug.WriteLine("Отправлено " + ii);
            }
        }
    }
}
вот такой получается результат
XML
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
Отправка 1
Получение 1
Поток '<Без имени>' (0x1c98) завершился с кодом 0 (0x0).
Отправка 10
Получение 10
Поток '<Без имени>' (0x1b28) завершился с кодом 0 (0x0).
Отправка 9
Получение 9
Поток '<Без имени>' (0x2350) завершился с кодом 0 (0x0).
Отправка 7
Получение 7
Поток '<Без имени>' (0x1d68) завершился с кодом 0 (0x0).
Отправка 8
Получение 8
Поток '<Без имени>' (0x2338) завершился с кодом 0 (0x0).
Отправка 6
Получение 6
Поток '<Без имени>' (0x20c4) завершился с кодом 0 (0x0).
Отправка 5
Получение 5
Поток '<Без имени>' (0x240) завершился с кодом 0 (0x0).
Отправка 4
Получение 4
Поток '<Без имени>' (0x1e8c) завершился с кодом 0 (0x0).
Отправка 2
Получение 2
Поток '<Без имени>' (0x470) завершился с кодом 0 (0x0).
Отправка 3
Получение 3
Поток '<Без имени>' (0x1f20) завершился с кодом 0 (0x0).
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
06.05.2013, 13:01
Ответы с готовыми решениями:

Синхронизация потоков
В общем идея была в том, что создаётся список потоков List&lt;Thread&gt; threads;. Все эти потоки...

Синхронизация потоков
Гуглю уже долго, а ответа все так и не нашел. Ситуация такая. У меня есть метод, который выполняют...

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

Синхронизация потоков
Не пойму своей ошибки в этих двух примерах кода, пожалуйста подскажите. Синхронизация с помощью...

36
Эксперт Java
4091 / 3825 / 745
Регистрация: 18.05.2010
Сообщений: 9,331
Записей в блоге: 11
06.05.2013, 15:13 2
Вам нужно именно этот код заставить работать (с множеством потоков) ?
Предложу вариант - сделать один дополнительный поток, который и будет делать всю работу, по очереди.

Вот тут можете посмотреть примеры решения с множеством потоков - http://stackoverflow.com/questions/3670914/serial-task-executor-is-this-thread-safe
1
7 / 7 / 1
Регистрация: 02.03.2011
Сообщений: 310
06.05.2013, 15:33  [ТС] 3
Цитата Сообщение от turbanoff Посмотреть сообщение
Вам нужно именно этот код заставить работать (с множеством потоков) ?
Нет, код другой.
Суть такая, есть модем, метод SSS - это имитация работы модема.
1. Запускается он из разных потоков.
2. Одновременно он тоже не может работать, все вызовы к нему должны ставиться в очередь.
3. Работать он должен в отдельном потоке, чтоб не тормозить работу программы.

Цитата Сообщение от turbanoff Посмотреть сообщение
Предложу вариант - сделать один дополнительный поток, который и будет делать всю работу, по очереди.
это выход
но я не знаю как это реализовать, работа с потоками у меня хромает
0
Эксперт Java
4091 / 3825 / 745
Регистрация: 18.05.2010
Сообщений: 9,331
Записей в блоге: 11
06.05.2013, 15:58 4
Пройдите по ссылке - там все четко и с примерами.
0
7 / 7 / 1
Регистрация: 02.03.2011
Сообщений: 310
06.05.2013, 18:09  [ТС] 5
Цитата Сообщение от turbanoff Посмотреть сообщение
Пройдите по ссылке - там все четко и с примерами.
Turbanoff, не могли бы вы помочь применить его к моей проблеме
Я к сожалению не смог разобраться в примере.
0
608 / 583 / 157
Регистрация: 29.06.2010
Сообщений: 1,620
07.05.2013, 17:34 6
возможно это поможет, но не уверен что требовалось именно это)

Кликните здесь для просмотра всего текста
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
using System;
using System.Collections.Generic;
 
namespace ConsoleTest
{
    public class Program
    {
        private static void QueueSSS_OnMessage(object sender, string message)
        {
            Console.WriteLine(sender.ToString() + ": " + message);
        }
 
        public static void Main()
        {
            QueueSSS que = new QueueSSS();
            que.OnMessage += QueueSSS_OnMessage;
 
            for (int i = 0; i < 3; i++)
                que.AddQueuer(i);
 
            que.Start();
            Console.ReadLine();
 
            que.Stop();
            Console.ReadLine();
        }
    }
 
    public delegate void StringHandler(object sender, string message);
 
    public class QueueSSS
    {
        public event StringHandler OnMessage;
 
        private ListSSS list = new ListSSS();
        private System.Threading.Thread tdQueuer;
 
        public bool isSending = true;
        public QueueSSS()
        {
            list.OnAdd += Message;
            list.OnSend += Message;
        }
 
        public void Start()
        {
            tdQueuer = new System.Threading.Thread(Send);
            tdQueuer.IsBackground = true;
            tdQueuer.Start();
        }
 
        private void Send()
        {
            try
            {
                Message(this, "Начато отправление запросов");
                while (isSending)
                {
                    System.Threading.Thread.Sleep(100);
                    list.sendNext();
                }
            }
            catch (System.Threading.ThreadAbortException)
            {
                Message(this, "Прекращение отправки запросов");
            }
        }
 
        public void Stop()
        { tdQueuer.Abort(); }
 
        public void AddQueuer(int number)
        { list.add(number); }
 
        public void Message(object sender, string message)
        {
            if (OnMessage != null)
                OnMessage(sender, message);
        }
    }
 
    public class ListSSS
    {
        public event StringHandler OnSend;
        public event StringHandler OnAdd;
 
        private List<int> numbers = new List<int>();
        public int lastSended = 0;
 
        public void add(int number)
        {
            numbers.Add(number);
            if (OnAdd != null) OnAdd(this, "Добавлен запрос #" + number);
        }
 
        public void sendNext()
        {
            lock (numbers)
            {
                if (numbers.Count > 0)
                {
                    new System.Threading.Thread(send).Start();
                }
            }
        }
 
        private void send()
        {
            lock (numbers)
            {
                lastSended = numbers[0];
                if (OnSend != null) OnSend(this, "Отправка #" + lastSended);
 
                System.Threading.Thread.Sleep(2000);
 
                numbers.RemoveAt(0);
                if (OnSend != null)  OnSend(this, "Получение  #" + lastSended);
            }
        }
    }
}
0
7 / 7 / 1
Регистрация: 02.03.2011
Сообщений: 310
07.05.2013, 21:52  [ТС] 7
Цитата Сообщение от Spectral-Owl Посмотреть сообщение
возможно это поможет, но не уверен что требовалось именно это)
Спасибо но немного не то.
1. В этом коде с начала добавляются запросы, а потом уже начинается их обработка.
А у меня, появляется запрос (в моем примере нажимаем на кнопку), начинается его обработка, пока она происходит может появиться еще запрос, он должен подождать пока выполнится первый и только потом начать выполняться, а пока он ждет может появиться третий и четвертый. Эти запросы генерируются программой, их может пройти 5 штук с интервалом 1 сек, а может 2 за пол дня. Чтоб модем не повис, они должны вставать в очередь.
2. Тут я так понимаю все запросы в одном потоке добавляются в коллекцию, а потом переходят в другой и там обрабатывается.
А у меня все запросы приходят из разных потоков и в итоге они должны встать в одну очередь.
0
go
Эксперт С++
3646 / 1378 / 243
Регистрация: 16.04.2009
Сообщений: 4,526
07.05.2013, 23:43 8
xxxspeed, задание можете сказать?
Цитата Сообщение от xxxspeed Посмотреть сообщение
вот такой простой код
Цитата Сообщение от xxxspeed Посмотреть сообщение
Подскажите как сделать так, чтоб потоки выполнялись по порядку
что значит по порядку?
0
7 / 7 / 1
Регистрация: 02.03.2011
Сообщений: 310
08.05.2013, 02:10  [ТС] 9
Цитата Сообщение от go Посмотреть сообщение
xxxspeed, задание можете сказать?
Цитата Сообщение от xxxspeed Посмотреть сообщение
Нет, код другой.
Суть такая, есть модем, метод SSS - это имитация работы модема.
1. Запускается он из разных потоков.
2. Одновременно он тоже не может работать, все вызовы к нему должны ставиться в очередь.
3. Работать он должен в отдельном потоке, чтоб не тормозить работу программы.
go, Я писал выше суть задачи, если в ней, что не понятно могу более подробно обьяснить.
Мне просто кажется я понятно изложился.

Цитата Сообщение от go Посмотреть сообщение
xxxspeed, что значит по порядку?
В моем примере нажатием кнопки button1 я имитирую поступление новой информации (i) на модем.
Проблема в том, что если несколько раз нажать на кнопку очередь запросов не выполнится по порядку 1,2,3,4,5,6... а получится вразноброс, как у меня 1,10,9,7,8,6,5,4,2,3.
0
Эксперт Java
4091 / 3825 / 745
Регистрация: 18.05.2010
Сообщений: 9,331
Записей в блоге: 11
08.05.2013, 07:46 10
Делаете поле класса - очередь из элементов int.
В главном потоке - добавляете элементы. Во втором - в бесконечном цикле вытаскиваете из очереди элементы и вызываете нужный код.
Вроде все просто.
0
608 / 583 / 157
Регистрация: 29.06.2010
Сообщений: 1,620
08.05.2013, 09:30 11
xxxspeed, я что-то не понял что в моём примере не удовлетворяет условию, разве что метод main(),
вот взгляд с другой стороны, классы не изменены.

Кликните здесь для просмотра всего текста
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
124
125
126
127
128
129
130
131
using System;
using System.Collections.Generic;
 
namespace ConsoleTest
{
    public class Program
    {
        private static void QueueSSS_OnMessage(object sender, string message)
        {
            Console.WriteLine(sender.ToString() + ": " + message);
        }
 
        public static void Main()
        {
            QueueSSS que = new QueueSSS();
            que.OnMessage += QueueSSS_OnMessage;
 
            int i;
            for (i = 0; i < 3; i++)
                que.AddQueuer(i);
 
           
            que.Start();
            Console.ReadLine();
 
            string end = "";
            while (end != "end")
            {
                end = Console.ReadLine();
                if (end!="end")
                    que.AddQueuer(i++);
            }
 
            que.Stop();
            Console.ReadLine();
        }
    }
 
    public delegate void StringHandler(object sender, string message);
 
    public class QueueSSS
    {
        public event StringHandler OnMessage;
 
        private ListSSS list = new ListSSS();
        private System.Threading.Thread tdQueuer;
 
        public bool isSending = true;
        public QueueSSS()
        {
            list.OnAdd += Message;
            list.OnSend += Message;
        }
 
        public void Start()
        {
            tdQueuer = new System.Threading.Thread(Send);
            tdQueuer.IsBackground = true;
            tdQueuer.Start();
        }
 
        private void Send()
        {
            try
            {
                Message(this, "Начато отправление запросов");
                while (isSending)
                {
                    System.Threading.Thread.Sleep(100);
                    list.sendNext();
                }
            }
            catch (System.Threading.ThreadAbortException)
            {
                Message(this, "Прекращение отправки запросов");
            }
        }
 
        public void Stop()
        { tdQueuer.Abort(); }
 
        public void AddQueuer(int number)
        { list.add(number); }
 
        public void Message(object sender, string message)
        {
            if (OnMessage != null)
                OnMessage(sender, message);
        }
    }
 
    public class ListSSS
    {
        public event StringHandler OnSend;
        public event StringHandler OnAdd;
 
        private List<int> numbers = new List<int>();
        public int lastSended = 0;
 
        public void add(int number)
        {
            numbers.Add(number);
            if (OnAdd != null) OnAdd(this, "Добавлен запрос #" + number);
        }
 
        public void sendNext()
        {
            lock (numbers)
            {
                if (numbers.Count > 0)
                {
                    new System.Threading.Thread(send).Start();
                }
            }
        }
 
        private void send()
        {
            lock (numbers)
            {
                lastSended = numbers[0];
                if (OnSend != null) OnSend(this, "Отправка #" + lastSended);
 
                System.Threading.Thread.Sleep(2000);
 
                numbers.RemoveAt(0);
                if (OnSend != null)  OnSend(this, "Получение  #" + lastSended);
            }
        }
    }
}
0
7 / 7 / 1
Регистрация: 02.03.2011
Сообщений: 310
08.05.2013, 10:56  [ТС] 12
Цитата Сообщение от Spectral-Owl Посмотреть сообщение
xxxspeed, я что-то не понял что в моём примере не удовлетворяет условию, разве что метод main(),
вот взгляд с другой стороны, классы не изменены.
Может я недопонимаю ваш код
Давайте пойдем другим путем,
вот мой код, кнопка генерирует запрос, т.е. цикла for (i = 0; i < 3; i++) не надо, его роль кнопка выполняет.
где я написал стартовая точка, с этой точки и начнем.
Вот хоть убейте, но я не смог подставить ваш код сюда.

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
using System;
using System.Diagnostics;
using System.Threading;
using System.Windows;
 
namespace WpfApplication1
{
    /// <summary>
    /// Логика взаимодействия для MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }
 
        private Thread t;
        private int i = 0;
        readonly object _syncLock = new object();
 
        private void button1_Click(object sender, RoutedEventArgs e)
        {
            i++;
            t = new Thread(Sms);
            t.Start(i);
        }
        private void Sms(object ii)
        {
            // Это стартовая точка
        }
    }
}
Добавлено через 5 минут
Цитата Сообщение от turbanoff Посмотреть сообщение
Делаете поле класса - очередь из элементов int.
В главном потоке - добавляете элементы. Во втором - в бесконечном цикле вытаскиваете из очереди элементы и вызываете нужный код.
Вроде все просто.
Вы знаете, всегда просто когда понимаешь.
В данном случае я не понимаю.
Если б понял я не просил бы помощи.
Я неделю промучался и запутался окончательно.
0
608 / 583 / 157
Регистрация: 29.06.2010
Сообщений: 1,620
08.05.2013, 11:20 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
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
namespace WinFormTest
{
    public partial class AllTest : Form
    {
        int i = 0;
        QueueSSS que;
        public AllTest()
        {
            InitializeComponent();
            que = new QueueSSS();
            que.OnMessage += QueueSSS_OnMessage;
 
            que.Start();
        }
 
        public void QueueSSS_OnMessage(object sender, string message)
        {
            if (this.InvokeRequired)
                this.BeginInvoke(new MethodInvoker(() => listBox1.Items.Add(sender.ToString() + ": " + message)));
            else
                listBox1.Items.Add(sender.ToString() + ": " + message);
        }
 
        private void button1_Click(object sender, EventArgs e)
        {
            que.AddQueuer(i++);
        }
    }
 
    public delegate void StringHandler(object sender, string message);
 
    public class QueueSSS
    {
        public event StringHandler OnMessage;
 
        private ListSSS list = new ListSSS();
        private System.Threading.Thread tdQueuer;
 
        public bool isSending = true;
        public QueueSSS()
        {
            list.OnAdd += Message;
            list.OnSend += Message;
        }
 
        public void Start()
        {
            tdQueuer = new System.Threading.Thread(Send);
            tdQueuer.IsBackground = true;
            tdQueuer.Start();
        }
 
        private void Send()
        {
            try
            {
                Message(this, "Начато отправление запросов");
                while (isSending)
                {
                    System.Threading.Thread.Sleep(100);
                    list.sendNext();
                }
            }
            catch (System.Threading.ThreadAbortException)
            {
                Message(this, "Прекращение отправки запросов");
            }
        }
 
        public void Stop()
        { tdQueuer.Abort(); }
 
        public void AddQueuer(int number)
        { list.add(number); }
 
        public void Message(object sender, string message)
        {
            if (OnMessage != null)
                OnMessage(sender, message);
        }
    }
 
    public class ListSSS
    {
        public event StringHandler OnSend;
        public event StringHandler OnAdd;
 
        private List<int> numbers = new List<int>();
        public int lastSended = 0;
 
        public void add(int number)
        {
            numbers.Add(number);
            if (OnAdd != null) OnAdd(this, "Добавлен запрос #" + number);
        }
 
        public void sendNext()
        {
            lock (numbers)
            {
                if (numbers.Count > 0)
                {
                    new System.Threading.Thread(send).Start();
                }
            }
        }
 
        private void send()
        {
            lock (numbers)
            {
                lastSended = numbers[0];
                if (OnSend != null) OnSend(this, "Отправка #" + lastSended);
 
                System.Threading.Thread.Sleep(2000);
 
                numbers.RemoveAt(0);
                if (OnSend != null) OnSend(this, "Получение  #" + lastSended);
            }
        }
    }
}


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

Кликните здесь для просмотра всего текста
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
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Threading;
 
namespace WinFormTest
{
    //класс-форма
    public partial class AllTest : Form
    {
        //текущий номер запроса
        int i = 0;
        // экземпляр класса-очереди запросов
        QueueSSS que;
 
        //конструктор формы
        public AllTest()
        {
            InitializeComponent();
 
            //создание экземпляра очереди
            que = new QueueSSS();
            //добавление обработчика на событие
            que.OnMessage += QueueSSS_OnMessage;
 
            //запуск автоотправления запросов
            que.Start();
        }
 
        //метод - обработчик события сообщения от очереди
        public void QueueSSS_OnMessage(object sender, string message)
        {
            //если нужно возвращение к базовому потоку
            if (this.InvokeRequired)
                //вывод сообщения в базовом потоке
                this.BeginInvoke(new MethodInvoker(() => listBox1.Items.Add(sender.ToString() + ": " + message)));
            else
                //вывод сообщения в текущем потоке потоке
                listBox1.Items.Add(sender.ToString() + ": " + message);
        }
 
        //метод - обработчик нажатия на кнопку
        private void button1_Click(object sender, EventArgs e)
        {
            //добавление ещё одного запроса
            que.AddQueuer(i++);
        }
    }//конец формы
 
    //делегат для работы с событиями-сообщениями
    public delegate void StringHandler(object sender, string message);
 
    //класс - очередь запросов
    public class QueueSSS
    {
        //событие на вывод сообщения
        public event StringHandler OnMessage;
 
        //экземпляр класса - списка неотправленных запросов
        private ListSSS list = new ListSSS();
        //поток для постоянной отправки запросов
        private System.Threading.Thread tdQueuer;
 
        //флаг работы потока
        public bool isSending = true;
 
        //конструктор класса
        public QueueSSS()
        {
            //добавление обработчиков событиям списка
            list.OnAdd += Message;
            list.OnSend += Message;
        }
 
        //запуск потока отправки запросов
        public void Start()
        {
            tdQueuer = new System.Threading.Thread(Send);
            tdQueuer.IsBackground = true;
            tdQueuer.Start();
        }
 
        //потоковый метод отправки запросов
        private void Send()
        {
            try
            {
                //вызов метода сообщения
                Message(this, "Начато отправление запросов");
                
                //пока установлен флаг...
                while (isSending)
                {
                    //небольшая остановка потока
                    System.Threading.Thread.Sleep(100);
                    //вызов метода отправки сообщения в списке неотправленных запросов
                    list.sendNext();
                }
            }
            //при прерывании работы потока
            catch (System.Threading.ThreadAbortException)
            {
                //вызов метода сообщения
                Message(this, "Прекращение отправки запросов");
            }
        }
 
        //метод остановки посылки
        public void Stop()
        { tdQueuer.Abort(); }
 
        //метод добавления запроса
        public void AddQueuer(int number)
        { list.add(number); }
 
        //метод выдачи сообщения
        public void Message(object sender, string message)
        {
            //если у события есть обработчик..
            if (OnMessage != null)
                //вызов события с переданными параметрами
                OnMessage(sender, message);
        }
    }//конец очереди
 
    //класс - список неотправленных запросов
    public class ListSSS
    {
        //событие на отправку
        public event StringHandler OnSend;
        //событие на добавление
        public event StringHandler OnAdd;
 
        //список неотправленных запросов
        private List<int> numbers = new List<int>();
        //номер последнего отправленного запроса
        public int lastSended = 0;
 
        //метод добавления запроса
        public void add(int number)
        {
            //добавление в список запроса
            numbers.Add(number);
            //вызов метода сообщения
            if (OnAdd != null) OnAdd(this, "Добавлен запрос #" + number);
        }
 
        //метод отправки сообщения (именно он постоянно вызывается в классе-обладателе)
        public void sendNext()
        {
            //синхронизация
            lock (numbers)
            {
                //если список не пустой
                if (numbers.Count > 0)
                {
                    //запуск нового потока отправки
                    new System.Threading.Thread(send).Start();
                }
            }
        }
 
        //метод отправки, вызываемый в новом потоке
        private void send()
        {
            //синхронизация
            lock (numbers)
            {
                //установка нового последнего отправленного
                lastSended = numbers[0];
                //сообщение об отправке
                if (OnSend != null) OnSend(this, "Отправка #" + lastSended);
 
                //ожидание (видимо тут должна быть обработка чего-либо, хотя я сделал-бы в другом методе)
                System.Threading.Thread.Sleep(2000);
 
                //удаление последнего отправленного
                numbers.RemoveAt(0);
                //отправка о якобы получении ответа
                if (OnSend != null) OnSend(this, "Получение  #" + lastSended);
            }
        }
    }//конец списка неотправленных
}
1
7 / 7 / 1
Регистрация: 02.03.2011
Сообщений: 310
08.05.2013, 12:09  [ТС] 14
Цитата Сообщение от Spectral-Owl Посмотреть сообщение
возможно имеет смысл добавить комментарии, вдруг поможет. ведь я собственно реализовал то что советовали выше, только немного странным способом)
Спасибо, разобрался, понял суть происходящего.
0
go
Эксперт С++
3646 / 1378 / 243
Регистрация: 16.04.2009
Сообщений: 4,526
08.05.2013, 12:30 15
Цитата Сообщение от xxxspeed Посмотреть сообщение
очередь запросов
Вот-вот. У вас я этой очереди не увидел. Я бы как-то так сделал. Для Вашего удобства все скинула в один файл. На форме кнопка и текстбокс.
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
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;
 
namespace Modem
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            modem = new MyModem(new ResultBox(textBox1));
        }
 
        private void AddQuery_Click(object sender, EventArgs e)
        {
            ++m_val;
            modem.AddQuery(m_val);
        }
 
        private MyModem modem;
        private int m_val = 0;
    }
 
    public interface IAddResult
    {
        void AddResult<T>(T res);
    }
 
    public class ResultBox : IAddResult
    {
        public ResultBox(TextBox textbox)
        {
            m_textbox = textbox;
            m_textbox.Clear();
        }
 
        public void AddResult<T>(T res)
        {
            m_textbox.Invoke(new Del((ress) => m_textbox.Text += " " + ress.ToString()), res);
        }
 
        delegate void Del(object text);
        private TextBox m_textbox;
    }
 
    public class MyModem
    {
        public MyModem(IAddResult resbox)
        {
            queue = new Queue<int>();
            thread = new Thread(DoWork);
            thread.IsBackground = true;
            thread.Start(resbox);
        }
 
        public virtual bool AddQuery(int val)
        {
            lock (queue)
            {
                queue.Enqueue(val);
                Monitor.Pulse(queue);
            }
 
            return true; // возврат bool для дольнейшей доработки класса, с целью добавления возможности его закрытия
        }
 
        private void DoWork(object param)
        {
            while (true)
            {
                lock (queue)
                {
                    while (queue.Count == 0)
                    {
                        Monitor.Wait(queue);
                    }
 
                    int val = queue.Dequeue();
 
                    ((IAddResult)param).AddResult(val);
                }
            }
        }
 
        protected Queue<int> queue;
        protected Thread thread;
    }
}
Добавлено через 17 минут
Я тут подумал. Можно еще так доделать. Вдруг у нас там что-то не понятное сделают в AddResult<T>
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
                    try
                    {
                        ((IAddResult)param).AddResult(val);
                    }
                    catch (Exception e)
                    {
                        ThreadAbortException ex = e as ThreadAbortException;
 
                        if (ex != null)
                        {
                            Thread.ResetAbort();
                        }
 
                        // что-нибудь делаем с exception
 
                    }
1
Master of Orion
Эксперт .NET
6098 / 4954 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
08.05.2013, 18:57 16
xxxspeed, многопоточность не гарантирует исчх не должна гарантировать определенной очередности выполнения потоков. Иначе никакой многопоточностью тут и не пахнет.
0
Эксперт Java
4091 / 3825 / 745
Регистрация: 18.05.2010
Сообщений: 9,331
Записей в блоге: 11
08.05.2013, 19:44 17
Psilon, ТС уже давно пояснил зачем ему нужна многопоточность, и что он подразумевает под этим словом, в рамках его задачи.
0
Master of Orion
Эксперт .NET
6098 / 4954 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
08.05.2013, 19:48 18
turbanoff, судя по всему ему нужно просто в фоне работать с асинхронной очередью, но тогда какие-то странные советы
0
Эксперт Java
4091 / 3825 / 745
Регистрация: 18.05.2010
Сообщений: 9,331
Записей в блоге: 11
08.05.2013, 19:52 19
Цитата Сообщение от Psilon Посмотреть сообщение
но тогда какие-то странные советы
Какой совет вам показался странным?
0
Master of Orion
Эксперт .NET
6098 / 4954 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
08.05.2013, 19:55 20
turbanoff, смутило использование одновременно монитора и lock, если учесть, что lock внутри себя использует монитор, получилось
0
08.05.2013, 19:55
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
08.05.2013, 19:55
Помогаю со студенческими работами здесь

Синхронизация потоков, мьютекс
я имею функцию, которую запускаю в несколько потоков public static void...

Синхронизация групп потоков
Здравствуйте! Помогите, пожалуйста. У меня есть метод MonitoringThread() в котором запускается 9...

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

Асинхронный сокет синхронизация потоков
Нужно сделать синхронизацию каталогов на сервере и на клиенте используя неблокирующий сокет....


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

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