Форум программистов
 
Контакты: о проблемах с регистрацией, почтой и по другим вопросам пишите сюда - alarforum@yandex.ru, проверяйте папку спам! Обязательно пройдите активизацию e-mail.

Вернуться   Форум программистов > .NET > Общие вопросы .NET
Регистрация

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

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

Цитата:
Сообщение от OmegaBerkut Посмотреть сообщение
Что интересно, одновременное чтение ресурса ссылочного типа всё равно не допускается. То есть, минимум lock всё равно нужен.
Кто запретил?
__________________
http://coub.com/view/2hhtg
pu4koff вне форума   Ответить с цитированием
Старый 29.03.2018, 15:57   #12
OmegaBerkut
Участник клуба
 
Аватар для OmegaBerkut
 
Регистрация: 19.03.2013
Сообщений: 881
Репутация: 111
По умолчанию

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

Цитата:
Сообщение от OmegaBerkut Посмотреть сообщение
Не знаю ... Отладчик наверное, но и без него программа выкидывает "Этот ресурс занят другим процессом" как то так.
Тут уже только конкретный код смотреть нужно. Что-то не так с GDI+ делается, судя по всему.
__________________
http://coub.com/view/2hhtg
pu4koff вне форума   Ответить с цитированием
Старый 29.03.2018, 18:52   #14
OmegaBerkut
Участник клуба
 
Аватар для OmegaBerkut
 
Регистрация: 19.03.2013
Сообщений: 881
Репутация: 111
По умолчанию

Цитата:
Сообщение от 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 в 18:55.
OmegaBerkut вне форума   Ответить с цитированием
Старый 29.03.2018, 19:34   #15
OmegaBerkut
Участник клуба
 
Аватар для OmegaBerkut
 
Регистрация: 19.03.2013
Сообщений: 881
Репутация: 111
По умолчанию

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

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

Я же говорю: рисовать из разных потоках - это не круто.
Или делать нормально, как все делают или разбираться что именно у GDI+ нельзя использовать из разных потоков. Image нельзя - синхронизировать, еще что-то нельзя - аналогично.
__________________
http://coub.com/view/2hhtg
pu4koff вне форума   Ответить с цитированием
Старый 29.03.2018, 20:32   #17
New man
Участник клуба
 
Регистрация: 24.01.2011
Сообщений: 685
Репутация: 241
По умолчанию

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


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

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

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

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

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

icq: 512-765
skype: alexp.frl
По умолчанию

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

Цитата:
Сообщение от OmegaBerkut Посмотреть сообщение
Но ведь я использую по контролу на поток.
Так нельзя, UI поток один.
При желании вроде можно извратиться и создать несколько UI потоков, но вряд ли это возможно для контролов в 1 окне.
Alex11223 вне форума   Ответить с цитированием
Старый 30.03.2018, 09:25   #20
Pavia
Лис
Профессионал
 
Аватар для Pavia
 
Регистрация: 18.09.2015
Сообщений: 1,469
Репутация: 1533
По умолчанию

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

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


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

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

Опции темы

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Быстрый переход

Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Поиск в памяти процесса Mr_ViK Общие вопросы Delphi 5 27.08.2012 21:38
Редактирование памяти процесса Dima DDM Общие вопросы Delphi 0 25.12.2010 17:54
Размер памяти процесса ZaRDaK Общие вопросы Delphi 5 25.09.2010 23:48
Редактирование памяти процесса Air Win Api 6 16.02.2008 21:15


08:53.


Powered by vBulletin® Version 3.8.8 Beta 2
Copyright ©2000 - 2018, Jelsoft Enterprises Ltd.

RusProfile.ru


Справочник российских юридических лиц и организаций.
Проекты отопления, пеллетные котлы, бойлеры, радиаторы
интернет магазин respective.ru