Форум программистов, компьютерный форум, киберфорум
Наши страницы
C# для начинающих
Войти
Регистрация
Восстановить пароль
 
XCemaXX
0 / 0 / 0
Регистрация: 24.02.2014
Сообщений: 4
#1

Работа с Dictionary в одном потоке, при этом он может изменятся в другом потоке - C#

24.02.2014, 14:01. Просмотров 754. Ответов 4
Метки нет (Все метки)

Здравствуйте!
Я делаю лабу сервер распределенных вычислений в сети.
В одном потоке ожидаю клиентов и на каждого клиента создаю поток.
C#
1
2
3
4
5
6
7
8
9
while (true)
            {
                counter += 1;
                clientSocket = serverSocket.AcceptTcpClient();//ждем очередного клиента
                Console.WriteLine(" >> " + "Client No:" + Convert.ToString(counter) + " started!");//подключился новый клиент
                handleClinet client = new handleClinet();
                Program.clients.Add(counter,false);//добавили в список клиента
                client.startClient(clientSocket, counter);//вызываем функцию обработки клиента. counter нигде не уменьшается, просто всегда растет. Клиенты не только добавляются, но и могут удаляться.
            }
В другом потоке жду пока введут задание на клавиатуре, после чего нужно пробегаться по списку клиентов, ища не занятого клиента и давая ему задания, пока эти задания не кончатся.
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
temp_c = n_com;
while (temp_c == n_com)//ждем, пока команда не сработает
                    {
                        foreach (KeyValuePair<int, bool> i in clients)//проходим по клиентам
                        {
                            if (i.Value)//отправить работу, если готов клиент
                            {
                                in_con = "decode " + i.Key.ToString();//меняем команду для клиента
                                n_com++;//сработала команда.
                                while (i.Value) { }//ожидаем, пока клиент не заработал
                                break;
                            }
                        }
Как клиент начинает работу:
C#
1
2
3
4
5
6
7
if ((Program.in_con == "decode " + clNo.ToString()) && (n_com_cur == Program.n_com))//clNo-номер клиента в списке, n_com_cur-номер последней выполненной команды. если команда для него и команда новая, то клиент начинает работу
{  
            Program.clients[clNo] = false;//не готов к работе клиент
//...отправка сообщений клиенту, прием сообщений
            n_com_cur++;
            Program.clients[clNo] = true;//готов к работе клиент
}
Проблема в том, что если оставить код таким, то i.Value никогда не измениться и программа уйдет в бесконечный цикл. Если сделать ожидания простоять 1000 шагов, то это бред и появляется ошибка: нельзя бегать по foreach, т.к. Dictionary изменился в другом потоке(Когда клиент начинает работу, он меняет свое значения занятости на false, когда заканчивает - true).
Вопрос: есть ли более оптимальный способ хранить список клиентов и их занятость? сейчас они хранятся в виде Dictionary<int, bool>. Если нет, то есть ли какой-либо другой способ пробегать список, чтобы была устойчивость к изменению Dictionary из другого потока, и не возникало гонок, т.е. основной процесс дожидался момента, когда выбранный им клиент заработает?
Заранее, спасибо!
0
Лучшие ответы (1)
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
24.02.2014, 14:01
Я подобрал для вас темы с готовыми решениями и ответами на вопрос Работа с Dictionary в одном потоке, при этом он может изменятся в другом потоке (C#):

Организация рассчетов в одном потоке, отрисовка графика по ним - в другом
Всем добрый вечер! Вот такая у меня проблема. На экране формы лежит...

Элементы управления, созданные в одном потоке, не могут быть родительскими для элемента управления в другом потоке
Привет :) Есть задача - нужно динамически добавлять компоненты. Все работает...

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

Создать приложение, в отдельном потоке вычисляющее значение w и непрерывно обновляющее его в потоке
Ребят, с потоками не работал не когда. Есть задание , я понимаю что хотят, а...

ProgressBar в другом потоке
Есть приложение, которое заносит в БД тысячи строк, соответственно форма...

Ивент с реакцией в другом потоке
В главном потоке происходит событие, к примеру А = 5. Как сделать так чтобы...

4
EVG-1980
190 / 197 / 82
Регистрация: 11.04.2013
Сообщений: 1,086
24.02.2014, 14:24 #2
Лучший ответ Сообщение было отмечено XCemaXX как решение

Решение

C#
1
2
3
4
Lock(Dictionary)
{
///
}
Не?

Добавлено через 4 минуты
http://msdn.microsoft.com/ru-ru/library/dd997305%28v=vs.110%29.aspx
1
XCemaXX
0 / 0 / 0
Регистрация: 24.02.2014
Сообщений: 4
24.02.2014, 17:05  [ТС] #3
Попробывал lock в паре с ConcurrentDictionary. С одним потоком работает корректно, только если поставить задержку после foreach(бегущему по ConcurrentDictionary). С двумя уже не работает, но походу проблема уже в коде, а именно в мое механизме запуска работы потока: проскакивают номера команд, т.е. когда происходит поиск свободного процесса, он находится, но ничего не выполняется=>счетчик не увеличивается. Буду пытаться что то сделать.=(
0
EVG-1980
190 / 197 / 82
Регистрация: 11.04.2013
Сообщений: 1,086
24.02.2014, 17:17 #4
Цитата Сообщение от XCemaXX Посмотреть сообщение
Попробывал lock в паре с ConcurrentDictionary.
Lock нужен для НЕ потокобезопасных коллекций, у потокобезопасных есть свои методы http://msdn.microsoft.com/ru-ru/library/dd997369(v=vs.110).aspx
0
XCemaXX
0 / 0 / 0
Регистрация: 24.02.2014
Сообщений: 4
25.02.2014, 12:44  [ТС] #5
Поменял свой ужасный код и списки, использовал lock с обычным list. Все работает, красота. Спасибо.
0
25.02.2014, 12:44
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
25.02.2014, 12:44
Привет! Вот еще темы с решениями:

Не ловит исключение в другом потоке
Thread thread = new Thread(cicle); thread.Start(); void cicle() { ...

Запуск метода в другом потоке
Здравствуйте) Есть отдельный поток(ListenerThread), в нем я пытаюсь обратиться...

Выполнение метода в другом потоке
Есть один синхронный метод из сторонней dllки, принимающий на вход массив байт...

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


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

Или воспользуйтесь поиском по форуму:
5
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru