Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум программистов > Разработка под ASP.NET > проблема с многопоточностью. |
Автор: dmitryk1 16.9.2015, 12:35 | ||||||
В системе использую объекты в которых лежат запросы к базе. запросов разных много и хранятся они в файлах. Некоторые редкие, некоторые выполняются очень часто. Для ускорения работы создал пул этих объектов и получаю их методом :
соответственно первое обращение объект кэширует, остальные используют уже имеющиеся объекты. Основная проблема возникает с частоиспользуемыми объектами, когда одновременно в разных потоках начинают запрашиваться одинаковые объекты и тут:
выдаётся ошибка что ключ уже добавлен. соответственно здесь:
его ещё не было. С этим можно как-то бороться? |
Автор: jsharp36 16.9.2015, 13:47 | ||||
даже не вникал особо в код, очевидная бага. Для многопоточного кода используйте или блокировки или специальные структуры данных. Dictionary не ходится для работы с разных потоков. Наиболее простой способ починить, это обернуть в lock.
Это самый надежный способ. Но будет вызывать блокировки. Можно иначе. (Я не проверяю код, если что, баги будут очевидные:
Тут возможно будет несколько раз создаваться репорт, пока не попадет в словарь. Если не использовать Add, а resp[rp] = rp;, то гарантированно падать не будет, если есть уже значение, то перезапишет. Вопрос только в оптимальности и можно ли два раза делать один и тот же репорт. Иногда блокировки будут хуже для производительности, иногда если часто пересекаются вызовы на одинаковые репорты, то репорты (особенно если там тяжелая в конструкторе логика). Если надо надежно только одному потоку, то блокируйте lock-ом Этот ответ добавлен с нового Винграда - http://ru.vingrad.com/problema-s-mnogopotochnostyu-id55f93808ae201526618b4567#findElement_E7045_55f948d1ae201537737f5d6a_0 |
Автор: dmitryk1 17.9.2015, 14:53 |
Спасибо, тоже уже в сторону лока смотрел. Но решил поконсультироваться. В принципе блокировки не особо страшны, поскольку отчёты добавляются в кэш только после чистки его или рестарта сервера, так что вариант более чем достаточный. Хотел уточнить - когда я подобный код с блокировками отлаживал, при дебаге он внутрь лока заходил несколькими потоками. Или при дебаге он на локи не смотрит? |