|
|
Регистрация Восстановить пароль |
Регистрация | Задать вопрос |
Заплачу за решение |
Новые сообщения |
Сообщения за день |
Расширенный поиск |
Правила |
Всё прочитано |
|
|
Опции темы | Поиск в этой теме |
29.03.2018, 14:39 | #11 |
Старожил
Регистрация: 22.05.2007
Сообщений: 9,085
|
Кто запретил?
|
29.03.2018, 14:57 | #12 |
Спокойный псих
Участник клуба
Регистрация: 19.03.2013
Сообщений: 1,538
|
Не знаю ... Отладчик наверное, но и без него программа выкидывает "Этот ресурс занят другим процессом" как то так.
Подпись ? Не, не слышал ...
|
29.03.2018, 15:56 | #13 |
Старожил
Регистрация: 22.05.2007
Сообщений: 9,085
|
Тут уже только конкретный код смотреть нужно. Что-то не так с GDI+ делается, судя по всему.
|
29.03.2018, 17:52 | #14 |
Спокойный псих
Участник клуба
Регистрация: 19.03.2013
Сообщений: 1,538
|
Возможно и "не так", и мне такая формулировка "нравится" ...
Мне кажется если что то действительно не так - то исключения должны сыпаться независимо от того, параллельный доступ к переменной, или же нет. Там кода много, поэтому вот ключевые места ... Что то вроде такого Код:
Если в наглую тырить объект для его отрисовки на Graphics - то исключения "занято" я получаю в случайных местах работы объекта (на столько же случайно, на сколько случайно поведение этих объектов). Метод переписовки вызывается из разных мест класса. Это значит, что кто то из соседей пытается стырить картинку в каком либо месте кода класса. Поэтому я беру, в конструкторах игровых объектов делаю Код:
Поэтому вешаю lock (input) { /* и радуюсь жизни */ }, ровно до тех пор, пока не выясняется, что по каким то причинам целевой Graphics оказывается повреждён. На этом этапе я попробовал "забить" на текущий объект, и вывалить его выполнение в небытие, но не тут то было ... По всей программе делегаты в Invoke начинают вешать выполнение, что делает невозможным дальнейшую работу с внешними данными. Целеой Graphics по вполне внятным причинам является "собственностью" объекта, и создаётся всё в том же конструкторе того же класса. Кстати, ввиду того, что картинку нужно иногда вертеть - объект изображения не один, а два: initialImage (он же innerImg) и currentImage. Зачем я так сделал - уже не помню, но меняется всегда именно второй объект, а первый пока просто висит в исходном состоянии, вдруг когда нибудь пригодится для перерисовки "с нуля градусов".
Подпись ? Не, не слышал ...
Последний раз редактировалось OmegaBerkut; 29.03.2018 в 17:55. |
29.03.2018, 18:34 | #15 |
Спокойный псих
Участник клуба
Регистрация: 19.03.2013
Сообщений: 1,538
|
Синхронизация потоков ничего не дала. Ну разве что отодвинула всё ту же ошибку, а ещё появились забавные тормоза.
Но если тормоза ещё можно решить допиливанием оптимизации, то вот с этой демонюгой я никак не справляюсь. Из чего я делаю вывод - что то тут не так ... Кстати, когда раньше была подобная проблема - она была ровно в том же самом месте (при попытке что то нарисовать на Graphics), отладчик не выкидывал исключение, а просто проглатывал его, без отладчика в трассировке не отображались мои методы, из чего я сделал вывод, что баг где то "дальше", и решил его самым обычным try-catch, после чего ошибка исчезла из виду (возможно носила периодически-хаотический характер, но ею можно было пренебречь). Сюда удачно подходит та самая формулировка:
Подпись ? Не, не слышал ...
|
29.03.2018, 19:30 | #16 |
Старожил
Регистрация: 22.05.2007
Сообщений: 9,085
|
Я же говорю: рисовать из разных потоках - это не круто.
Или делать нормально, как все делают или разбираться что именно у GDI+ нельзя использовать из разных потоков. Image нельзя - синхронизировать, еще что-то нельзя - аналогично. |
29.03.2018, 19:32 | #17 |
Форумчанин
Регистрация: 24.01.2011
Сообщений: 774
|
Вообще, всё это странно.
Сделай по-нормальному. В одном потоке выводи картинку, в другом потоке считай изменения игры (вот тут можно распареллелить с Parallel.ForEach) и рисуй (в один поток). GDI даёт exception именно потому, что замечает, что её пытаются использовать неправильно.
a.k.a. Angelicos Phosphoros
Мой сайт |
29.03.2018, 20:05 | #18 |
Спокойный псих
Участник клуба
Регистрация: 19.03.2013
Сообщений: 1,538
|
Но ведь я использую по контролу на поток. Ресурс то монопольный. Какая разница, из какого потока выполняется рисование, если нет помех от соседей ?
Повесил отрисовку на родной поток (Invoke): 1) предыдущая проблема не исчезла; 2) появилась новая проблема, скрин вложил; ошибка выпала в Program.cs. В прочем ладно, если я не победю это, то буду переделывать. Хотя логика то правильная. Видите ли, GDI(+) что то не нравится. На плюсах в MFC такой проблемы нет. Там вообще плевать, если есть доступ - то работать будет. Но блин, задача то на шарпе стоит ...
Подпись ? Не, не слышал ...
|
29.03.2018, 23:48 | #19 | |
Старожил
Регистрация: 12.01.2011
Сообщений: 19,500
|
Цитата:
Так нельзя, UI поток один. При желании вроде можно извратиться и создать несколько UI потоков, но вряд ли это возможно для контролов в 1 окне.
Ушел с форума, https://www.programmersforum.rocks, alex.pantec@gmail.com, https://github.com/AlexP11223
ЛС отключены Аларом. |
|
30.03.2018, 08:25 | #20 |
Лис
Старожил
Регистрация: 18.09.2015
Сообщений: 2,409
|
Любой общий ресурс подлежит защите. Это простое правило осталось научится его применять.
Конечно хорошо что вы к каждому контролу обращаетесь из своего потока. Но кто сказал что контролы потоко-безопасны? Эти контролы небось обращаются к общим ресурсам. Во всяком случае они рисуют на общей форме, общем окне и общем экране! А значит внутри этих контролов нужно разместить защиту от обращения к общей форме и к другим общим ресурсам. Стоит понимать что форма это общий ресурс как и GDI тоже общий ресурс. И для работы с потоками в GDI есть функция GdiFlush(). Вот в Delphi почти все контролы достаточно безопасны там рисование идёт в OnPaint. А Вызов OnPaint происходит через очередь-сообщений. Очередь-сообщений это один из примитивов синхронизации. Но рисования такое происходит в основном потоке. На вашем месте я бы работал с контралми из основного потока.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
У дзен программиста программа делает то что он хотел, а не то что он написал . |
|
Похожие темы | ||||
Тема | Автор | Раздел | Ответов | Последнее сообщение |
Поиск в памяти процесса | Mr_ViK | Общие вопросы Delphi | 5 | 27.08.2012 21:38 |
Редактирование памяти процесса | Dima DDM | Общие вопросы Delphi | 0 | 25.12.2010 16:54 |
Размер памяти процесса | ZaRDaK | Общие вопросы Delphi | 5 | 25.09.2010 23:48 |
Редактирование памяти процесса | Air | Win Api | 6 | 16.02.2008 20:15 |