Форум программистов, компьютерный форум, киберфорум
C# .NET
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.86/21: Рейтинг темы: голосов - 21, средняя оценка - 4.86
64 / 65 / 44
Регистрация: 05.12.2014
Сообщений: 475

Обезопасить доступ к коллекции из разных потоков

02.12.2016, 12:52. Показов 5047. Ответов 37
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
станет ли безопасным метод AddSafe?
C#
1
2
3
4
5
6
7
8
9
10
11
12
public static MyCollection myCol = new MyCollection();
 
class MyCollection: ObservableCollection<string>
{
    public void AddSafe(string item)
    {
        lock(this)
        {
            this.Add(item);
        }
    }
}
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
02.12.2016, 12:52
Ответы с готовыми решениями:

Заполнение коллекции из разных потоков
Добрый день. Что я могу использовать вместо удобной ObservableCollection&lt;T&gt;, если мне надо добавлять данные из разных потоков?

Одновременный доступ к коллекции из двух потоков
Здравствуйте. В программе открываю UDP-сокет, в который приходят данные с устройства. Вкратце, у меня выглядит это так: public void...

Доступ к БД с разных потоков
как реализовать доступ к одной базе данных с разных потоков? когда один сервер обрабатывает несколько клиентов то у меня выходит...

37
64 / 65 / 44
Регистрация: 05.12.2014
Сообщений: 475
07.08.2017, 18:30  [ТС]
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от kolorotur Посмотреть сообщение
Где-нибудь в вашем коде производится подписка на события этой коллекции?
Вы имеете ввиду что-то вроде рекурсивного вызова методов одной и той-же коллекции? Вроде нет такого.

Цитата Сообщение от kolorotur Посмотреть сообщение
не дай бог, асинхронные вызовы вперемешку с замыканиями.
Сначала я лочил в разных местах кода, сейчас удалил их все вместе с лок-объектами и сделал один лок внутри коллекции, так что такого тоже не должно быть.

Может ли это быть связанным с тем что я использую Thread-ы а не Task-и ?
0
Эксперт .NET
 Аватар для kolorotur
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
07.08.2017, 18:48
Цитата Сообщение от Jotun Посмотреть сообщение
Вы имеете ввиду что-то вроде рекурсивного вызова методов одной и той-же коллекции?
Нет, я про подписку на событие CollectionChanged где-нибудь у вас в коде.

Цитата Сообщение от Jotun Посмотреть сообщение
начала я лочил в разных местах кода
Асинхронный код (async/await) в тех местах не используется?
0
64 / 65 / 44
Регистрация: 05.12.2014
Сообщений: 475
08.08.2017, 16:37  [ТС]
Нет, таких вещей нету.

У меня только один вариант - взять SynchronizationContext UI и делать всё там без локов, но это же фигня полная
0
Эксперт .NET
 Аватар для kolorotur
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
08.08.2017, 16:39
Jotun, если есть возможность — подцепите проект, глянем.
0
484 / 397 / 68
Регистрация: 14.02.2014
Сообщений: 1,930
08.08.2017, 16:42
Извиняюсь за странный вопрос. А почему бы не воспользоваться потокобезопасными коллекциями?
0
Эксперт .NET
 Аватар для kolorotur
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
08.08.2017, 16:45
aquaMakc, возможно, автору требуется поддержка INotifyCollectionChanged, которую реализуют не все готовые потокобезопасные коллекции.
0
64 / 65 / 44
Регистрация: 05.12.2014
Сообщений: 475
08.08.2017, 16:47  [ТС]
Цитата Сообщение от kolorotur Посмотреть сообщение
Асинхронный код (async/await) в тех местах не используется?
похоже что используется
C#
1
Vars.RequestList.AddSafe(request);
выглядит так:
C#
1
2
3
4
5
public void AddSafe(Request request)
{
    Vars.uiContext.Send(x => this.Add(request), null);
// uiContext - это SynchronizationContext главного потока, т.к. в другом менять коллекцию не даёт.
}
т.е. вторичный поток ждёт ответа от основного на SynchronizationContext.Send, а основной ждёт когда разблокируется лок во вторичном.
0
484 / 397 / 68
Регистрация: 14.02.2014
Сообщений: 1,930
08.08.2017, 16:52
Цитата Сообщение от kolorotur Посмотреть сообщение
INotifyCollectionChanged, которую реализуют не все готовые потокобезопасные коллекции.
Мне кажется, эту проблему решить проще, чем велосипедить свою потокобезопасную коллекцию.
0
Эксперт .NET
 Аватар для kolorotur
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
08.08.2017, 17:03
Jotun, так удалите этот синхронный вызов, зачем он там?

aquaMakc, я могу ошибаться, но вроде в дотнете нет готового потокобезопасного списка?
0
484 / 397 / 68
Регистрация: 14.02.2014
Сообщений: 1,930
08.08.2017, 17:06
Цитата Сообщение от kolorotur Посмотреть сообщение
я могу ошибаться, но вроде в дотнете нет готового потокобезопасного списка?
Можно воспользоваться например этим, или этим.
0
64 / 65 / 44
Регистрация: 05.12.2014
Сообщений: 475
08.08.2017, 17:08  [ТС]
Цитата Сообщение от kolorotur Посмотреть сообщение
Jotun, так удалите этот синхронный вызов, зачем он там?
ну остаётся только использовать Post я так понимаю?
0
Эксперт .NET
 Аватар для kolorotur
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
08.08.2017, 17:15
Цитата Сообщение от aquaMakc Посмотреть сообщение
Можно воспользоваться например этим, или этим.
Ни тот, ни другой не подходят по функционалу, если судить по приведенным ранее кускам кода — нет произвольного доступа к элементам, например для удаления.

Цитата Сообщение от Jotun Посмотреть сообщение
ну остаётся только использовать Post я так понимаю?
Зачем?
Используйте EnableCollectionSynchronization, передайте в него тот же объект, что вы используете для синхронизации в коллекции и поудаляйте вызовы Send/Post — пусть фреймворк сам синхронизирует.
1
64 / 65 / 44
Регистрация: 05.12.2014
Сообщений: 475
08.08.2017, 17:20  [ТС]
Цитата Сообщение от kolorotur Посмотреть сообщение
Используйте EnableCollectionSynchronization, передайте в него тот же объект, что вы используете для синхронизации в коллекции и поудаляйте вызовы Send/Post — пусть фреймворк сам синхронизирует.
Действительно, перестало кидать исключение что коллекция меняется в другом потоке
0
64 / 65 / 44
Регистрация: 05.12.2014
Сообщений: 475
21.08.2017, 22:23  [ТС]
Снова появился вопрос(идея) Сейчас если я изменяю данные конкретного объекта коллекции - то лочу всю коллекцию, выглядит это так примерно:

C#
1
2
3
4
5
6
7
8
9
10
L2Creature crt = Vars.CreaturesList.GetItemByObjectID(objId);
if (crt != null)
{
    lock (Vars.CreaturesList._lock)
    {
        crt.X = x;
        crt.Y = y;
        crt.Z = z;
    }
}
Тут один и тот-же lock объект используется дважды - в методе GetItemByObjectID() и перед присваиванием переменных.

А что если у каждого объекта коллекции будет свой _lock, и если нужно изменять данные только одного объекта - то использовать этот "локальный" лок?
Будет ли это более эффективным?

Если я буду удалять элемент коллекции - можно ли будет использовать лок самого объекта?
C#
1
2
lock(object._lock)
    this.Remove(object)
0
Эксперт .NET
 Аватар для kolorotur
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
21.08.2017, 23:04
Цитата Сообщение от Jotun Посмотреть сообщение
Будет ли это более эффективным?
Да, потому что изменяется конкретный объект. Синхронизируясь на конкретном объекте, вы уменьшите количество ненужных блокировок.

Цитата Сообщение от Jotun Посмотреть сообщение
Если я буду удалять элемент коллекции - можно ли будет использовать лок самого объекта?
Нет, потому что при удалении изменяется не объект, а вся коллекция.
1
64 / 65 / 44
Регистрация: 05.12.2014
Сообщений: 475
22.09.2017, 19:54  [ТС]
И снова здраствуйте Объясните пож. такой момент.
Вот я использую ConcurrentDictionary
C#
1
2
3
4
5
6
7
8
9
10
ConcurrentDictionary<int, L2MapObject> MapObjectsList
 
// В одном потоке обращаюсь к словарю по ключу:
            if (Vars.MapObjectsList.ContainsKey(objId))
            {
                L2MapObject mo = Vars.MapObjectsList[objId];
                mo.X = x;
                mo.Y = y;
                mo.Z = z;
            }
Но получается что если полсе "if" поток переключится на другой - где этот объект удаляется, то у меня будет ошибка - ключа не существует. Значит всё равно этот словарь нужно локать
0
Эксперт .NET
 Аватар для kolorotur
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
22.09.2017, 22:44
Цитата Сообщение от Jotun Посмотреть сообщение
Значит всё равно этот словарь нужно локать
Да, но это только потому, что вы его неправильно используете.
Для правильного использования смотрите его методы, начинающиеся на Try — через них реализована потокобезопасность.
0
64 / 65 / 44
Регистрация: 05.12.2014
Сообщений: 475
23.09.2017, 08:46  [ТС]
Возмём тогда для примера ConcurrentDictionary<TKey, TValue>.TryGe tValue Method (TKey, TValue)
У него есть: ArgumentNullException : key is null.
Значит в случае выше указанного примера это не поможет?

Добавлено через 7 минут
А всё понял, если ключа не будет то просто не запишется значение
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
23.09.2017, 08:46

Доступ к очереди из разных потоков
Подскажите по многопоточности, у меня есть очередь (Queue) и мне надо организовать к ней доступ из разных потоков, выискал несколько...

Доступ к стриму из разных потоков
Задача такая, имеем мемористрим, в одном потоке постоянно пишем его. В другом потоке необходимо по запросу считывать весь поток в...

Доступ к функции с разных потоков C++ Builder
Как правильно объявить/создать функцию в C++Builder, чтобы она была доступна со всех потоков, включая главный? И как потом в этой функции...

Обеспечить корректный доступ к элементу из разных потоков
Возникла такая проблема. Есть приложение и в приложение есть элемент, к которому прикреплён некий код, который долго выполняется из-за...

Доступ к файлам из разных потоков, как исключить коллизии?
Разные потоки осуществляют чтение разных файлов произвольным образом командой System.IO.FileStream(NameFile, FileMode.Open). Иногда, при...


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

Или воспользуйтесь поиском по форуму:
38
Ответ Создать тему
Новые блоги и статьи
Запустил конкурс "тем и промптов для текстовых квестов созданных почти чисто ИИ"
Adler 06.10.2026
Всем привет! За последние три-четыре дня я создал более 16 текстовых квестовых игр используя преимущественно по одному запросу к ИИ на игру. Мне так понравилось смотреть все ветки/ сцены во всех. . .
ИИ не может найти нужный язык в списке
Supersumestria 05.10.2026
Я ему даю вот такое изображение и прошу найти и подчеркнуть немецкий язык. Возвращает он вот это: https:/ / i. **********/ vqBWLe2. png Нужную строчку в 3й колонке просто выдумал. . Это. . .
Новая последняя моя музыка в SUNO
zorxor 05.10.2026
Здравствуйте, дорогие мои друзья! С большой радостью я хотел бы представить вам свою новую последнею музыку, которую сгенерировала мне по моей просьбе нейросеть SUNO. С уважением, zorxor. Это. . .
Nekobox - outbounds[0].transport: unknown transport type: raw
damix 01.10.2026
Фикс ошибки Правым кликом по серверу -> отладочная информация -> edit Заменить "net": "raw", на "net": "tcp", Нажать кнопку reload.
Программный домашний кинотеатр
russiannick 27.09.2026
Сподобился на программный домашний кинотеатр. В качестве ЯВУ по традиции выбрал js. В помощники взял Яндекс-Алису. Было создано три зала на разные интересы. исторические и ретро сериал Хичкок. . .
Беседа с ИИ о программистах, недопускающих к созданию и правке кода генеративные ИИ и причины этого
zorxor 21.09.2026
Раньше я радовался или получал некоторые эмоции, пусть небольшие, но всё же, от самого процесса написания кода, рекомпиляции и запуска, видя постепенное развитие программы и прочее. А теперь лень. . .
Мобильное приложение ColorStep
pavlinmavlin 17.09.2026
Реализовал приложение Красный, Зеленый, Синий в Unity3d + c#. Название изменил на ColorStep. Приложение прошло модерацию и теперь доступно для скачивания. Делал его сам, шаг за шагом — и вот,. . .
Запрет дублирования строк в табличной части
Maks 13.09.2026
Реализация из решения ниже выполнена на нетиповом справочнике "Нормы ТО" с табличной часть "Виды ТО", разработанного в КА2, со следующими реквизитами: - ВидТО (СправочникСсылка. ВидыТО); - ВидГСМ. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru