Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > .NET Frameworks (точка нет фреймворки) > Общие вопросы .NET
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 29.03.2018, 14:39   #11
pu4koff
Старожил
 
Аватар для pu4koff
 
Регистрация: 22.05.2007
Сообщений: 9,520
По умолчанию

Цитата:
Сообщение от OmegaBerkut Посмотреть сообщение
Что интересно, одновременное чтение ресурса ссылочного типа всё равно не допускается. То есть, минимум lock всё равно нужен.
Кто запретил?
pu4koff вне форума Ответить с цитированием
Старый 29.03.2018, 14:57   #12
OmegaBerkut
Спокойный псих
Участник клуба
 
Аватар для OmegaBerkut
 
Регистрация: 19.03.2013
Сообщений: 1,538
По умолчанию

Цитата:
Сообщение от pu4koff Посмотреть сообщение
Кто запретил?
Не знаю ... Отладчик наверное, но и без него программа выкидывает "Этот ресурс занят другим процессом" как то так.
Подпись ? Не, не слышал ...
OmegaBerkut вне форума Ответить с цитированием
Старый 29.03.2018, 15:56   #13
pu4koff
Старожил
 
Аватар для pu4koff
 
Регистрация: 22.05.2007
Сообщений: 9,520
По умолчанию

Цитата:
Сообщение от OmegaBerkut Посмотреть сообщение
Не знаю ... Отладчик наверное, но и без него программа выкидывает "Этот ресурс занят другим процессом" как то так.
Тут уже только конкретный код смотреть нужно. Что-то не так с GDI+ делается, судя по всему.
pu4koff вне форума Ответить с цитированием
Старый 29.03.2018, 17:52   #14
OmegaBerkut
Спокойный псих
Участник клуба
 
Аватар для OmegaBerkut
 
Регистрация: 19.03.2013
Сообщений: 1,538
По умолчанию

Цитата:
Сообщение от pu4koff Посмотреть сообщение
то-то не так с GDI+ делается, судя по всему
Возможно и "не так", и мне такая формулировка "нравится" ...
Мне кажется если что то действительно не так - то исключения должны сыпаться независимо от того, параллельный доступ к переменной, или же нет.

Там кода много, поэтому вот ключевые места ...
Что то вроде такого
Код:
private Image fireShotImg;
public Image FireShotImg { get { return fireShotImg; } }
Висит на форме, подгружается при старте формы из файла, классы игрового поля и игровых объектов получают прямой/косвенный доступ к свойству.
Если в наглую тырить объект для его отрисовки на Graphics - то исключения "занято" я получаю в случайных местах работы объекта (на столько же случайно, на сколько случайно поведение этих объектов). Метод переписовки вызывается из разных мест класса. Это значит, что кто то из соседей пытается стырить картинку в каком либо месте кода класса.
Поэтому я беру, в конструкторах игровых объектов делаю
Код:
innerImg=(Image)input.Clone();
Предполагается, что этот код может и должен выполняться параллельно. Но, при больших нагрузках именно в этом месте я получаю всё то же исключение "занято", т. е. сосед пытается сделать тоже самое.
Поэтому вешаю lock (input) { /* и радуюсь жизни */ }, ровно до тех пор, пока не выясняется, что по каким то причинам целевой Graphics оказывается повреждён.
На этом этапе я попробовал "забить" на текущий объект, и вывалить его выполнение в небытие, но не тут то было ...
По всей программе делегаты в Invoke начинают вешать выполнение, что делает невозможным дальнейшую работу с внешними данными.
Целеой Graphics по вполне внятным причинам является "собственностью" объекта, и создаётся всё в том же конструкторе того же класса.
Кстати, ввиду того, что картинку нужно иногда вертеть - объект изображения не один, а два: initialImage (он же innerImg) и currentImage. Зачем я так сделал - уже не помню, но меняется всегда именно второй объект, а первый пока просто висит в исходном состоянии, вдруг когда нибудь пригодится для перерисовки "с нуля градусов".
Подпись ? Не, не слышал ...

Последний раз редактировалось OmegaBerkut; 29.03.2018 в 17:55.
OmegaBerkut вне форума Ответить с цитированием
Старый 29.03.2018, 18:34   #15
OmegaBerkut
Спокойный псих
Участник клуба
 
Аватар для OmegaBerkut
 
Регистрация: 19.03.2013
Сообщений: 1,538
По умолчанию

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

Но если тормоза ещё можно решить допиливанием оптимизации, то вот с этой демонюгой я никак не справляюсь. Из чего я делаю вывод - что то тут не так ...
Кстати, когда раньше была подобная проблема - она была ровно в том же самом месте (при попытке что то нарисовать на Graphics), отладчик не выкидывал исключение, а просто проглатывал его, без отладчика в трассировке не отображались мои методы, из чего я сделал вывод, что баг где то "дальше", и решил его самым обычным try-catch, после чего ошибка исчезла из виду (возможно носила периодически-хаотический характер, но ею можно было пренебречь).
Сюда удачно подходит та самая формулировка:
Цитата:
Сообщение от pu4koff Посмотреть сообщение
Что-то не так с GDI+ делается
Подпись ? Не, не слышал ...
OmegaBerkut вне форума Ответить с цитированием
Старый 29.03.2018, 19:30   #16
pu4koff
Старожил
 
Аватар для pu4koff
 
Регистрация: 22.05.2007
Сообщений: 9,520
По умолчанию

Я же говорю: рисовать из разных потоках - это не круто.
Или делать нормально, как все делают или разбираться что именно у GDI+ нельзя использовать из разных потоков. Image нельзя - синхронизировать, еще что-то нельзя - аналогично.
pu4koff вне форума Ответить с цитированием
Старый 29.03.2018, 19:32   #17
New man
Форумчанин
 
Регистрация: 24.01.2011
Сообщений: 774
По умолчанию

Вообще, всё это странно.


Сделай по-нормальному.
В одном потоке выводи картинку, в другом потоке считай изменения игры (вот тут можно распареллелить с Parallel.ForEach) и рисуй (в один поток).

GDI даёт exception именно потому, что замечает, что её пытаются использовать неправильно.
a.k.a. Angelicos Phosphoros
Мой сайт
New man вне форума Ответить с цитированием
Старый 29.03.2018, 20:05   #18
OmegaBerkut
Спокойный псих
Участник клуба
 
Аватар для OmegaBerkut
 
Регистрация: 19.03.2013
Сообщений: 1,538
По умолчанию

Цитата:
Сообщение от pu4koff Посмотреть сообщение
нельзя использовать из разных потоков
Но ведь я использую по контролу на поток. Ресурс то монопольный. Какая разница, из какого потока выполняется рисование, если нет помех от соседей ?

Повесил отрисовку на родной поток (Invoke):
1) предыдущая проблема не исчезла;
2) появилась новая проблема, скрин вложил; ошибка выпала в Program.cs.

В прочем ладно, если я не победю это, то буду переделывать.
Хотя логика то правильная. Видите ли, GDI(+) что то не нравится.
На плюсах в MFC такой проблемы нет. Там вообще плевать, если есть доступ - то работать будет. Но блин, задача то на шарпе стоит ...
Изображения
Тип файла: png lol.png (26.8 Кб, 38 просмотров)
Подпись ? Не, не слышал ...
OmegaBerkut вне форума Ответить с цитированием
Старый 29.03.2018, 23:48   #19
Alex11223
Старожил
 
Аватар для Alex11223
 
Регистрация: 12.01.2011
Сообщений: 19,500
По умолчанию

Цитата:
Сообщение от OmegaBerkut Посмотреть сообщение
Там вообще плевать, если есть доступ - то работать будет. Но блин, задача то на шарпе стоит ...
Ну в С++ и за пределы массива можно писать, если не повезет, то ошибки не будет.

Цитата:
Сообщение от OmegaBerkut Посмотреть сообщение
Но ведь я использую по контролу на поток.
Так нельзя, UI поток один.
При желании вроде можно извратиться и создать несколько UI потоков, но вряд ли это возможно для контролов в 1 окне.
Ушел с форума, https://www.programmersforum.rocks, alex.pantec@gmail.com, https://github.com/AlexP11223
ЛС отключены Аларом.
Alex11223 вне форума Ответить с цитированием
Старый 30.03.2018, 08:25   #20
Pavia
Лис
Старожил
 
Аватар для Pavia
 
Регистрация: 18.09.2015
Сообщений: 2,409
По умолчанию

Любой общий ресурс подлежит защите. Это простое правило осталось научится его применять.
Конечно хорошо что вы к каждому контролу обращаетесь из своего потока. Но кто сказал что контролы потоко-безопасны? Эти контролы небось обращаются к общим ресурсам. Во всяком случае они рисуют на общей форме, общем окне и общем экране! А значит внутри этих контролов нужно разместить защиту от обращения к общей форме и к другим общим ресурсам.

Стоит понимать что форма это общий ресурс как и GDI тоже общий ресурс. И для работы с потоками в GDI есть функция GdiFlush().


Вот в Delphi почти все контролы достаточно безопасны там рисование идёт в OnPaint. А Вызов OnPaint происходит через очередь-сообщений. Очередь-сообщений это один из примитивов синхронизации. Но рисования такое происходит в основном потоке.

На вашем месте я бы работал с контралми из основного потока.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
У дзен программиста программа делает то что он хотел, а не то что он написал .
Pavia вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Поиск в памяти процесса 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