Новинки IT-индустрии, обзоры и тесты компьютеров и комплектующих
- ПК и комплектующие
- Настольные ПК и моноблоки
- Портативные ПК
- Серверы
- Материнские платы
- Корпуса
- Блоки питания
- Оперативная память
- Процессоры
- Графические адаптеры
- Жесткие диски и SSD
- Оптические приводы и носители
- Звуковые карты
- ТВ-тюнеры
- Контроллеры
- Системы охлаждения ПК
- Моддинг
- Аксессуары для ноутбуков
- Периферия
- Принтеры, сканеры, МФУ
- Мониторы и проекторы
- Устройства ввода
- Внешние накопители
- Акустические системы, гарнитуры, наушники
- ИБП
- Веб-камеры
- KVM-оборудование
- Цифровой дом
- Сетевые медиаплееры
- HTPC и мини-компьютеры
- ТВ и системы домашнего кинотеатра
- Технология DLNA
- Средства управления домашней техникой
- Гаджеты
- Планшеты
- Смартфоны
- Электронные ридеры
- Портативные медиаплееры
- GPS-навигаторы и трекеры
- Носимые гаджеты
- Автомобильные информационно-развлекательные системы
- Зарядные устройства
- Аксессуары для мобильных устройств
- Фото и видео
- Цифровые фотоаппараты и оптика
- Видеокамеры
- Фотоаксессуары
- Обработка фотографий
- Монтаж видео
- Программы и утилиты
- Операционные системы
- Средства разработки
- Офисные программы
- Средства тестирования, мониторинга и диагностики
- Полезные утилиты
- Графические редакторы
- Средства 3D-моделирования
- Мир интернет
- Веб-браузеры
- Поисковые системы
- Социальные сети
- «Облачные» сервисы
- Сервисы для обмена сообщениями и конференц-связи
- Разработка веб-сайтов
- Мобильный интернет
- Полезные инструменты
- Безопасность
- Средства защиты от вредоносного ПО
- Средства управления доступом
- Защита данных
- Сети и телекоммуникации
- Проводные сети
- Беспроводные сети
- Сетевая инфраструктура
- Сотовая связь
- IP-телефония
- NAS-накопители
- Средства управления сетями
- Средства удаленного доступа
- Корпоративные решения
- Системная интеграция
- Проекты в области образования
- Электронный документооборот
- «Облачные» сервисы для бизнеса
- Технологии виртуализации
Наш канал на Youtube
Архив изданий
1999 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | |
2000 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
2001 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
2002 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
2003 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
2004 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
2005 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
2006 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
2007 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
2008 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
2009 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
2010 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
2011 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | |
2013 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
- О нас
- Размещение рекламы
- Контакты
Популярные статьи
Моноблок HP 205 G4 22 AiO — одно из лучших решений для офисной и удаленной работы
В настоящем обзоре мы рассмотрим модель моноблока от компании HP, которая является признанным лидером в производстве компьютеров как для домашнего использования, так и для офисов.
Моноблок HP 205 G4 22 — модель нового семейства, которая построена на базе процессоров AMD последнего поколения и отличается неплохой производительностью вкупе с привлекательной ценойLogitech G PRO X Superlight — легкая беспроводная мышь для профессиональных киберспортсменов
Швейцарская компания Logitech G представила беспроводную игровую мышь Logitech G PRO X Superlight. Новинка предназначена для профессиональных киберспортсменов, а слово Superlight в ее названии указывает на малый вес этой модели, который не превышает 63 г. Это почти на четверть меньше по сравнению с анонсированным пару лет тому назад манипулятором Logitech G PRO Wireless
Материнская плата для домашнего майнинга ASRock h210 Pro BTC+
Как показало недавнее исследование Кембриджского университета — количество людей, которые пользуются сегодня криптовалютами, приближается к размеру населения небольшой страны и это только начало, мир меняется. Поэтому компания ASRock разработала и выпустила в продажу весьма необычную материнскую плату — h210 PRO BTC+, которую мы и рассмотрим в этом обзоре
Верхняя панель клавиатуры Rapoo Ralemo Pre 5 Fabric Edition обтянута тканью
Компания Rapoo анонсировала в Китае беспроводную клавиатуру Ralemo Pre 5 Fabric Edition. Новинка выполнена в формате TKL (без секции цифровых клавиш) и привлекает внимание оригинальным дизайном. Одна из отличительных особенностей этой модели — верхняя панель, обтянутая тканью с меланжевым рисунком
Изогнутый экран монитора MSI Optix MAG301 CR2 обеспечит максимальное погружение в игру
Линейку компьютерных мониторов MSI пополнила модель Optix MAG301 CR2, адресованная любителям игр. Она оборудована ЖК-панелью типа VA со сверхширокоформатным (21:9) экраном изогнутой формы (радиус закругления — 1,5 м). Его размер — 29,5 дюйма по диагонали, разрешение — 2560×1080 пикселов
Комплект SilverStone MS12 позволяет превратить SSD типоразмера M.2 2280 в портативный накопитель
Каталог продукции компании SilverStone пополнил комплект MS12. Он позволяет создать портативный накопитель на базе стандартного SSD типоразмера M.2 2280 с интерфейсом PCI Express
SSD-накопители ADATA XPG Spectrix S20G сочетают производительность с эффектным дизайном
Компания ADATA Technology анонсировала твердотельные накопители серии XPG Spectrix S20G. Они предназначены для оснащения игровых ПК и, как утверждают их создатели, сочетают высокую производительность и эффектный внешний вид
Видеокарта ASUS GeForce RTX 3070 Turbo оснащена системой охлаждения с одним центробежным вентилятором
Линейку видеоадаптеров ASUS на базе графических процессоров NVIDIA пополнила модель GeForce RTX 3070 Turbo (заводской индекс TURBO-RTX3070-8G), предназначенная для оснащения игровых ПК. Одной из особенностей новинки является конструкция системы охлаждения
КомпьютерПресс использует
Вопросы по Embarcadero RAD Studio XE5-XE8,10.x(Seattle, Berl | Прикладное программирование
← Вернуться в раздел «Прикладное программирование»
Автор: AlekXL
Дата сообщения: 29.09.2013 09:18
кстати, че-то вокруг QT 5 серьезная движуха началась, как мне показалось..(ранее мне она игрушкой для нердов представлялась)
По тону дискуссий на форумах выходит, что люди уже что-то серьезное на QT пилят(в отличие от FMX).
Получается, QT сейчас предподчтительнее для мобайла, чем FMX+Delphi?
Автор: ego666
Дата сообщения: 30.09.2013 05:16
Цитата:
Получается, QT сейчас предподчтительнее для мобайла, чем FMX+Delphi?
полистал немного гугл.. пока не очень то получается, тот же геммор, что и у Delphi: баги, низкая производительность, большой размер бинарника, плюс помимо этого, там где у делфи некоторые вещи «из коробки» — на qt приходиться пилить руками (судя по мануалам).
Добавлено:
попробую сейчас поставить сборку qt под винду, если осилю — выложу тут откомпилированные демки.
Автор: AlekXL
Дата сообщения: 30.09.2013 11:58
Цитата:
попробую сейчас поставить сборку qt под винду, если осилю — выложу тут откомпилированные демки.
у меня почти получилось. . На ютубе видео пошаговой настройки. Но..
компилятор спотыкается на том, что у мну andorid SDK в program files, явно пробел в пути ему не нравиться. Придется наверное симв ссылку делать.
А еще говорят Линукс и его софт вполне юзабельные… Лжецы позорные: даже длинные пути толком не реализованы, как это было на «венде» десять лет назад
—
Кстатии, а что возвращает AtomicCmpExchange? Прошлое значение? Или как?
Автор: Arioch2
Дата сообщения: 30.09.2013 12:08
Цитата:
А еще говорят Линукс и его софт вполне юзабельные
Человек ставит ANDROID sdk на WINDOWS и все свои проблемы списывает нa LINUX, который к этому никаким боком не относится. Чудесно 😀
Автор: X11
Дата сообщения: 30.09.2013 12:31
т.е. виндовый ANDROID sdk для винды не предназначен и у линуска не бывает пробелов и кириллицы?
Автор: Arioch2
Дата сообщения: 30.09.2013 12:35
Цитата:
виндовый ANDROID sdk для винды не предназначен
Понятия не имею. И при чем тут это?
Речь про то, что если у человека в Экселе проблемы — это Линукс тут не виноват никак.
Даже если в Линуксе тоже можно чем-то экселевские файлы открывать.
> у линуска не бывает пробелов и кириллицы
У линукса много чего бывает… Но что касается имён файлов, то по-моему у него ограничение то ли на 1КБ, то ли на 4 КБ, а у винды — 32КБ/UTF16 на имя файла. Остальное с именами файлов ЕМНИП там не хуже.
Добавлено:
Цитата:
Кстатии, а что возвращает AtomicCmpExchange? Прошлое значение? Или как?
По идее это «ручка» для вызова CMPXCHG — смотри что оно оставляет в EAX/RAX
http://ru.wikipedia.org/wiki/Сравнение_с_обменом
Надо будет документаторам написать, конечно, чтобы не пропускали этот вопрос.
Автор: ego666
Дата сообщения: 30.09.2013 12:45
Цитата:
у меня почти получилось.. На ютубе видео пошаговой настройки.
да у меня тоже почти, докачиваю sdk/ndk/jdk. Дай на всякий случай ту инструкцию на ютубе, а то если ещё придётся ручками прописывать пути для arm компилятора и создавать его профиль — чувствую убьюсь об стену..
Цитата:
компилятор спотыкается на том, что у мну andorid SDK в program files, явно пробел в пути ему не нравиться. Придется наверное симв ссылку делать
Такая же байда у меня была и с XE5, он по умолчанию запинхул sdk/ndk в Документы, пришлось подключать папку с ними как сетевой диск (хотя можно было и тупо переместить…)
Автор: AlekXL
Дата сообщения: 30.09.2013 13:17
Цитата:
Понятия не имею. И при чем тут это?
Речь про то, что если у человека в Экселе проблемы — это Линукс тут не виноват никак.
Даже если в Линуксе тоже можно чем-то экселевские файлы открывать.
У линукса много чего бывает. .. Но что касается имён файлов, то по-моему у него ограничение то ли на 1КБ, то ли на 4 КБ, а у винды — 32КБ/UTF16 на имя файла. Остальное с именами файлов ЕМНИП там не хуже.
ой ладно! Речь о том, что тулчейн qt-android — тупо линуксовый порт, и где-то в этом тулчейне не обрабатываются пути с пробелами.
Добавлено:
Цитата:
Дай на всякий случай ту инструкцию на ютубе, а то если ещё придётся ручками прописывать пути для arm компилятора и создавать его профиль — чувствую убьюсь об стену..
http://www.youtube.com/watch?v=_nkhlhBwkjk
Автор: Arioch2
Дата сообщения: 30.09.2013 13:21
т.е. в том, что линуксовая прога плохо работает на винде — виноваты линуксоиды ?
в общем-то чушь.
Виноваты виндузятники, которые захотели запустить на винде линуксовую прогу, но не смогли.
а линуксоиды соответственно будут виноваты, когда какая-то виндовая программа будет плохо работать на линуксе.
но не наоборот.
Автор: AlekXL
Дата сообщения: 30.09.2013 13:44
Цитата:
т.е. в том, что линуксовая прога плохо работает на винде — виноваты линуксоиды ?
Цитата:
Виноваты виндузятники, которые захотели запустить на винде линуксовую прогу, но не смогли.
виноваты те, кто программу портировали. Программисты с Линуксом Головного Мозга в терминальной стадии.
Цитата:
а линуксоиды соответственно будут виноваты, когда какая-то виндовая программа будет плохо работать на линуксе.
ерунда. во-первых нетути таковских софтин практически. А если и есть, то там от ничего от виндоус не осталось(линь не настолько гибкая)
—
Цитата:
По идее это «ручка» для вызова CMPXCHG — смотри что оно оставляет в EAX/RAX
http://ru.wikipedia.org/wiki/Сравнение_с_обменом
ты бы еще меня в гугль послал. Много там букафф, и не по делу.
В итоге выяснилось, что и врямь предыдущее/неизмененное значение приемника возвращается
Автор: Arioch2
Дата сообщения: 30.09.2013 13:51
Цитата:
виноваты те, кто его портировали. Программисты с Линуксом Головного Мозга
Цитата:
Виноваты те, кто рожают. Mужики.
Выбери уж что-нибудь одно. Или черное, или белое. Но не называй одно другим.
Линуксоиды очевидно портируют софт НА линукс. Портировать софт на ВИНДУ линуксоиды не могут и не хотят. На винду портируют очевидно ВИНДУЗЯТНИКИ, которым чего-то не хватает и хочется утянуть с линукса готовое.
Добавлено:
Цитата:
Много там букафф, и не по делу.
Там протокол, который твоя функция реализует или должна реализовать.
Автор: AlekXL
Дата сообщения: 30.09.2013 16:38
Цитата:
Линуксоиды очевидно портируют софт НА линукс. Портировать софт на ВИНДУ линуксоиды не могут и не хотят.
насчет не могут — это близко к истине. А вот «не хотят» — это только в идеальном мире.
Очень многие линуксоиды, думается, вынуждены использовать Windows для игр, или на работе. Windows это не то,что можно игнорировать.
И уж конечно, android-sdk портировали на Windows не фанаты Windows. Это делали профессионалы, и скорей всего, линуксоиды, поскольку именно такие работают в Google.
—
Цитата:
Там протокол, который твоя функция реализует или должна реализовать
мне нужна суть, а не официоз. Нет времени на него.
Автор: Arioch2
Дата сообщения: 30.09.2013 21:45
> Нет времени на него
Уж извини, те, у кого нет времени, открывают исходник и читают. Или проверяют на тестовой программе — всего-то два варианта проверить.
А не на форуме спрашивают, где то ли через час ответят, то ли через месяц.
———-
Цитата:
Это делали профессионалы, и скорей всего, линуксоиды
Хром для Windows тоже линуксоиды делают?
Гугл достаточно богатый, чтобы нанимать профессионалов, и не сажать яблочников на линукс ,а линуксоидов на винду.
Автор: GuSoft2007
Дата сообщения: 30.09.2013 22:28
пля, и тут холивар. сёня прям аншлаг, на нескольких сайтах уже вижу
никак заслали казачков на многие сайты рейтинг эмбаркадеро снизить и переманить всех. куда? ну известно куда, кто у нас vs выпускаит ) и сокращение названия продукта такое — сразу видно чего задумали
Автор: Arioch2
Дата сообщения: 30.09.2013 22:41
Вот интересно, если все покупатели Дельфи, наслушавшись злых нас, вместо XE5 купят свежий VS — это составит хоть 1% покупок ? Майкрософт хоть заметит изменения ?
Автор: ego666
Дата сообщения: 01.10.2013 09:56
какой же тормоз этот qt, сейчас вообще висит уже час и тихо кушает память.
Добавлено:
Цитата:
т.е. в том, что линуксовая прога плохо работает на винде — виноваты линуксоиды ?
есть подозрение, что оно и в люнухе не будет работать с пробелами/кириллицей в путях.
Автор: AlekXL
Дата сообщения: 01.10.2013 11:46
Цитата:
Хром для Windows тоже линуксоиды делают?
Гугл достаточно богатый, чтобы нанимать профессионалов, и не сажать яблочников на линукс ,а линуксоидов на винду.
не знаю как его делают, но хром под вынью даже настройки прокси берет у IE. Интерфейс бедный.. как для идиотов.
Я бы не сказал , что это от изобилия девелоперов под Windows.
—
А это нормально, что при копировании old object c VMT, члены копируются, а в VMT мусор или ноль..
Автор: ego666
Дата сообщения: 01.10.2013 12:47
Цитата:
Ошибка при сборке/установке проекта Demo (комплект: Android для arm (GCC 4. 8, Qt 5.1.1) )
Во время выполнения этапа «Установка на устройство Android»
бинарник .so создаётся, но apk нету. или может кто подскажет как тупо собрать apk без деплоя на устройство?
Автор: Arioch2
Дата сообщения: 01.10.2013 15:01
Цитата:
есть подозрение, что оно и в люнухе не будет работать с пробелами/кириллицей в путях
Не исключено. Но сначала надо это подозрение сделать фактом, и тоьлк опотом гнать на гугловских (а не на любых) линуксоидов.
Потому как именно линуксовые, а не андроидные, проги — например VLC, GIMP, Eclipse — работают и с пробелами, и с кириллицей.
С кириллицей у VLC впрочем в некоторых местах есть проблемы, но тут именно по причине довольно специфических фокусов с кириллицей в винде, на которые европоязычным виндузятники, переносящим VLC с линукса, по барабану
Добавлено:
Цитата:
Интерфейс бедный. . как для идиотов.
Это идеология. Неидиоты все разрулят плагинами, типа. А широким массам чем меньше кнопок- тем лучше. В идеале — ноль.
Автор: AlekXL
Дата сообщения: 01.10.2013 15:21
вот еще вопрос: можно ли вызывать методы апи для контролов Windows из побочного потока?
Автор: jorgik
Дата сообщения: 01.10.2013 15:49
AlekXL
Цитата:
А это нормально, что при копировании old object c VMT, члены копируются, а в VMT мусор или ноль..
Такое поведение также имеет место быть, например, и в Delphi 6. Результирующий объект должен быть проинициализирован. А мусор или ноль там, потому что это содержимое стека, т.к. переменная не проинициализирована.
Автор: ego666
Дата сообщения: 01.10.2013 20:08
Цитата:
можно ли вызывать методы апи для контролов Windows из побочного потока?
в смысле оконные сообщения слать? можно.
Автор: AlekXL
Дата сообщения: 02.10.2013 12:37
интересно, а почему в окне событий отладки отображаются и подгрузка библиотек, и запуск потоков, и даже бряки, а вот exception-ы — нет?
—
является ли TEvent.Wait — alertable блокировкой? типа для APC? Если нет, то есть ли код или либа, наследуемая от TEvent с данной функциональностью?
Автор: Frodo_Torbins
Дата сообщения: 02.10.2013 15:53
AlekXL
Цитата:
является ли TEvent.Wait — alertable блокировкой? типа для APC? Если нет, то есть ли код или либа, наследуемая от TEvent с данной функциональностью?
Потратил две минуты на изучение исходников и MSDN. Предлагаю и вам сделать то же самое.
Цитата:
интересно, а почему в окне событий отладки отображаются и подгрузка библиотек, и запуск потоков, и даже бряки, а вот exception-ы — нет?
У меня на ХЕ3 вроде отображаются.
Автор: AlekXL
Дата сообщения: 03.10.2013 05:31
Цитата:
Потратил две минуты на изучение исходников и MSDN. Предлагаю и вам сделать то же самое.
я тоже. Нет. TEvent.Wait не является алертабл, во всяком случае, если если не установлен USEComWait, а вот если установлен, то ХЗ.
Просто я больше доверяю чужому отлаженному коду больше, чем своему…
Цитата:
У меня на ХЕ3 вроде отображаются
да , кажется, ступил.
Автор: MagistrAnatol
Дата сообщения: 03.10.2013 08:49
Господа подскажите — что за прикол с компиляцией под андроид — сначала студия ругалась на неверный символ в environment.proj — сама блин создала и ей видите ли пробел не нравится — убрал.
В СДК пути подкоректирровал — но постоянно ругается
[DCC Fatal Error] F1026 File not found: ‘C:\Documents and Settings\All Users\Документы\RAD Studio\12. 0\PlatformSDKs\adt-bundle-windows-x86-20130522\sdk\build-tools\18.1.0\arm-linux-androideabi-ld.exe’
студии что повылазило или мне ?????
Автор: Arioch2
Дата сообщения: 03.10.2013 09:45
русскоязычные пути ?… а она случайно bat-файлы не использует ?
в любом случае, делай как всегда: SysInternals Process Monitor и смотришь что именно и где именно на самом деле пытался MSBuild найти
Автор: MagistrAnatol
Дата сообщения: 03.10.2013 09:51
Arioch2
возможно проблема и в русских путях , или я провтыкал — но что-то я не видел выбор каталога при установке СДК
Автор: mcka
Дата сообщения: 03.10.2013 10:15
Всем привет,
Посмотрите, пожалуйста, есть ли в XE5 файл XSLProd.pas (class TXSLPageProducer)
c:\Program Files\Embarcadero\RAD Studio\12.0\source\internet\
При установке выключал компоненты, в результате у меня отсутствует данный файл. Пробовал сделать modify — файл не появился (((
Хочу понять это глюк modify или в XE5 порезали source\internet\
Автор: X11
Дата сообщения: 03.10.2013 10:34
Цитата:
[DCC Fatal Error] F1026 File not found: ‘C:\Documents and Settings\All Users\Документы\RAD Studio\12.0\PlatformSDKs\adt-bundle-windows-x86-20130522\sdk\build-tools\18.1.0\arm-linux-androideabi-ld.exe’
студии что повылазило или мне ?????
убери кириллицу
Страницы: 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
Предыдущая тема: Отмена встречи в Outlook из Excel VBA
Форум Ru-Board.club — поднят 15-09-2016 числа. Цель — сохранить наследие старого Ru-Board, истории становления российского интернета. Сделано для людей.
Многопоточность. Как определить, что установлено TEvent?
спросил
Изменено 10 лет, 1 месяц назад
Просмотрено 5к раз
В документации Delphi XE2 о TEvent сказано следующее:
Иногда вам нужно дождаться завершения какой-либо операции потоком, а не ждать завершения выполнения определенного потока. Для этого используйте объект события. Объекты событий (System.SyncObjs.TEvent) должны создаваться с глобальной областью действия, чтобы они могли действовать как сигналы, видимые для всех потоков.
Когда поток завершает операцию, от которой зависят другие потоки, он вызывает TEvent.SetEvent. SetEvent включает сигнал, поэтому любой другой проверяющий поток будет знать, что операция завершена. Чтобы отключить сигнал, используйте метод ResetEvent.
Например, рассмотрим ситуацию, когда необходимо дождаться завершения выполнения нескольких потоков, а не одного потока. Поскольку вы не знаете, какой поток завершится последним, вы не можете просто использовать метод WaitFor одного из потоков. Вместо этого вы можете сделать так, чтобы каждый поток увеличивал счетчик по завершении, а последний поток сигнализировал, что все они выполнены, устанавливая событие.
Однако в документации Delphi не объясняется, как другой поток может определить, что было вызвано событие TEvent.Set. Не могли бы вы объяснить, как проверить, был ли вызван TEvent.Set?
- многопоточность
- делфи
2
Если вы хотите проверить, было ли сигнализировано событие или нет, вызовите метод WaitFor
и передайте значение тайм-аута, равное 0. Если событие установлено, оно вернет wrSignaled
. В противном случае он немедленно истечет время ожидания и вернет wrTimeout
.
При этом обычное использование события заключается не в проверке того, было ли оно сигнализировано таким образом, а в синхронизации путем блокировки текущего потока до тех пор, пока событие не будет сигнализировано. Вы делаете это, передавая ненулевое значение параметру тайм-аута, либо константу INFINITE
, если вы уверены, что он завершится, и вы хотите подождать, пока это не произойдет, либо меньшее значение, если вы не хотите блокировать для неопределенное количество времени.
2
Зарегистрируйтесь или войдите в систему
Зарегистрируйтесь с помощью Google
Зарегистрироваться через Facebook
Зарегистрируйтесь, используя адрес электронной почты и пароль
Опубликовать как гость
Электронная почта
Требуется, но никогда не отображается
Опубликовать как гость
Электронная почта
Требуется, но не отображается
Как работает механизм событий в Delphi: Реализация подписки на события.
| by SoftacomDelphi — это действительно инструмент RAD (быстрая разработка приложений). Одним из доказательств того, что это не просто маркетинговый ход, является то, что некоторые разработчики годами работают в Delphi IDE и даже не знают, как работает механизм событий, которым они пользуются каждый день. IDE делает процесс настолько простым, что после добавления кнопки на форму и двойного клика по ней можно написать код, который потом каким-то «волшебным образом» запустится в программе. И это описание вполне устраивает разработчиков, так как пользоваться этим механизмом можно абсолютно не разбираясь в деталях.
Но давайте углубимся в этот вопрос. Это будет полезно для создания собственных компонентов, а также для понимания всех плюсов и минусов такого подхода. Нам нужно проанализировать, как это работает с точки зрения конечного разработчика. Давайте создадим приложение Windows VCL с одной формой и добавим туда кнопку.
Затем нам нужно сделать двойной щелчок по кнопке и IDE отправит нас на реализацию метода Button1Click. Мы должны написать следующий код:
Теперь компилируем, запускаем код и нажимаем кнопку:
Все работает. Теперь пришло время посмотреть, как это работает и что IDE сделала вместо нас.
Сначала IDE проверила, какое событие должно быть принято. Затем он проверил, не был ли уже назначен другой процессор. Если бы он был назначен, IDE активировала бы режим отображения кода и показала бы его. Поскольку процессора не было, IDE использовала механизм RTTI (информация о типе времени выполнения) и взяла тип события OnClick — TNotifyEvent.
TNotifyEvent является процедурным типом и входит в группу указателей методов благодаря присоединению «объекта». Благодаря тому, что TNotifyEvent — это указатель на метод, OnClick — это событие, а не просто публичное свойство, как, например, Caption.
Далее IDE взяла имена и типы параметров из TNotifyEvent, нашла тип нашей формы в файле PAS в секции интерфейса (так как это родительский компонент нашей кнопки), создала метод с именем Button1Click ( [Имя компонента] + [Имя компонента без включения]) и параметры из TNotifyEvent.
После создания реализации заданного метода редактор переключается в режим отображения кода и фокус перемещается на реализацию этого метода. Более того, вновь созданный метод был сохранен в свойстве OnClick. IDE отображается следующим образом:
А в виде файла DFM это выглядит так:
Как видите, всю монотонную работу, связанную с созданием и назначением события, выполнила IDE. А разработчику нужно написать только необходимый код. Но в некоторых случаях может возникнуть необходимость организовать его в ручном режиме в RUNTIME, поэтому может быть полезно знать, как это можно сделать.
Мы проанализировали, как работает назначение обработчиков событий с точки зрения IDE и разработчиков, а теперь давайте посмотрим на компонентную сторону. Нам нужно рассмотреть, как организован механизм вызова наших назначенных процессоров.
Возьмем такое же событие OnClick той же кнопки Button1. Здесь мы опустим всю иерархию наследования класса TButton и перейдем непосредственно к его предку TControl. Очень важно знать, что событие OnClick наследуется от него.
Событие имеет тип TNotifyEvent, как мы упоминали ранее, и его чтение и запись выполняются непосредственно в поле FOnClick. Теперь нам нужно понять, где и как используется поле:
Метод Click показывает, как осуществляется вызов события. Если опустить все детали реализации для TAction, то логика достаточно проста: если поле FOnClick не пустое, то нужно вызвать этот метод в то место, куда он указывает. В качестве параметра Sender нам нужно отправить себя (в нашем случае это будет копия Button1). Не будем вдаваться в подробности обработки сообщений MouseDown и MouseUp. Достаточно будет просто сказать, что когда мы указываем, что клик был сделан, вызывается метод Click.
Практически все события реализованы в системе одинаково. Если вам нужно включить дополнительные параметры, вы должны использовать соответствующий тип, такой как TNotifyEvent.
Что касается плюсов этой реализации, то она проста в организации и использовании, особенно с учетом помощи IDE. Дополнительным плюсом является то, что один метод может быть назначен несколькими компонентами, если они имеют одинаковый тип. Повторное использование кода вместо дублирования всегда является хорошим вариантом. Параметр Sender предназначен для понимания того, какой компонент вызвал наш процессор.
Что касается минусов, то среди них следует отметить анонимность и отсутствие информации о жизненном цикле Владельца метода со стороны нашего компонента. Это может звучать довольно странно и запутанно. Немного поясню этот момент. Технически ничто не может помешать нам назначить обработчик из другой формы для нажатия нашей Button1 (если их параметры совпадают) и все будет работать корректно. Но если вторая форма будет удалена, то наша кнопка не получит об этом никакой информации и сохранит указатель метода на удаленный объект в поле FOnClick, что может привести к ошибкам при вызове метода. Однако такой случай с нажатием кнопки на практике маловероятен. Но если рассматривать разработку какого-либо модуля API с использованием TRestClient и TRESTResponse, например, особенно в асинхронном режиме, то это может быть проблемой. Второй минус — отсутствие возможности назначить несколько обработчиков на одно событие.
Попробуем разобраться с этими минусами.
Чтобы максимально упростить наш пример, мы не будем писать генератор асинхронных событий, но в то же время не будем зацикливаться только на нашей теории.
Задача будет следующая: у нас многомониторная система. По умолчанию на каждом мониторе нам нужно открыть форму и отобразить в ней время, но пользователь может дополнительно открывать и закрывать формы со временем. Организация одновременного изменения времени во всех формах – очень важный момент.
Первая идея, которая может прийти вам в голову, это поместить все формы для времени в отдельный список и проверить список на OnTimer и изменить записи. Но, во-первых, никто не может гарантировать, что в будущем не добавятся новые формы с разными форматами отображения. А во-вторых, наше «ядро» должно будет знать обо всех типах и объектах, которые должны получать от него время. Поэтому лучшим решением будет создать что-то вроде ядра, которое будет генератором событий и организовать подписки на события изменения времени. Это не сложная задача. Итак, начнем. Давайте создадим DataModule и разместим на нем Timer. Наш модуль будет ядром нашей программы. А наш таймер будет отвечать за генерацию событий для обеспечения синхронного изменения времени.
Теперь нам нужно создать тип наших событий. Обычный TNotifyEvent нам не подойдет, так как в нем нет параметра времени. Мы можем назвать наш тип, например, TTimeChangeEvent и включить параметр текущего времени:
Если на этом этапе мы просто объявим поле FTimeChangeEvent: TimeChangeEvent, то это будет просто классическое использование событий. Но в нашем случае он нам не подходит из-за множественных подписок на одно событие. Это означает, что мы должны хранить несколько событий. Можно объявить поле, которое будет списком событий (TList
Итак, для удобства создадим новый тип TTimeChangeSubscribers = TDictionary
Не забывайте, что для использования TDictionary необходимо добавить модуль System.Generics.Collections в раздел uses. Мы также должны написать инициализацию/финализацию нашего списка для событий модуля данных OnCreate\OnDestroy:
Теперь нужно реализовать публичные методы подписки и отписки от получения событий:
Метод подписки прост в реализации. Нам нужно добавить или заменить компонент и его обработчик событий в нашем списке. Мы сохраним их вместе, чтобы иметь возможность корректно найти и удалить процесс в момент отписки. Во второй строке мы включим механизм Free Notification, чтобы получать уведомления, если наш подписчик будет удален. Подробнее о механизме бесплатных уведомлений вы можете прочитать в одной из наших ранее опубликованных статей.
Отписка тоже выполняется одной строкой кода, но чтобы не ошибиться нужно добавить пару проверок, не был ли уже удален список и подписан ли компонент, который пытается отписаться.
И вот мы подошли к самой важной части — вызову наших обработчиков событий. Весь код может быть написан в процессоре OnTimer. Но если мы хотим сделать все правильно, нам нужно создать виртуальный защищенный метод DoTimeChange. Это поможет, если однажды кому-то понадобится изменить или расширить логику в классах-предках нашего ядра.
Код достаточно прост:
- проверить уничтожение
- запомнить время, которое будет отправлено нашим подписчикам
- запустить цикл во всех процессорах в списке
- если текущий процессор не нулевой, вызвать его.
Последнее, что нам нужно сделать с нашим ядром, это настроить его реакцию на удаление абонента.
Переопределить защищенный метод Notification и добавить несколько строк кода.
Таким образом у нас будет автоматическая отписка перед удалением подписчика. Ядро готово.
Опишем форму для отображения данных: создаем новую форму, добавляем метку. Если вы хотите, вы также можете выбрать шрифт и выравнивание. Затем реализуем метод обработки события TimeChange. Я назвал его MyTimeChange (параметры должны совпадать с типом TTimeChangeEvent). Реализация проста: нужно перенести полученное в параметрах время в строку и добавить Label1.Caption.
Теперь давайте создадим обработчики событий на FormCreate и FormClose.
На FormCreate мы должны зарегистрировать наш процессор в «ядре». На FormClose мы должны прикрепить значение caFree к переменной Action, чтобы удалить форму, а не просто скрывать ее при закрытии.
И последнее, что нам осталось сделать, это добавить на главную форму кнопку создания форм с отображением времени.
Теперь создадим обработчик событий нажатия кнопки:
Вот и все. На всех мониторах нашей системы вы увидите формы, которые будут отображать время. Они будут автоматически подписываться и отписываться от событий ядра.
Давайте проверим, как работает наша система автоматической отписки. Теперь закрываем форму и видим метод TfmTimeForm.FormClose.
Теперь добавим индикатор того, что форму надо удалить и двигаться дальше. Обработчик событий реагирует на наш индикатор и запускает механизм уничтожения формы, который, в свою очередь, запускает механизм FreeNotification. FreeNotification проверит список подписчиков на уведомления об уничтожении и найдет их наше «ядро». Таким образом, мы попадем в TdmTimeModule.Notification.
Здесь мы просто запускаем наш стандартный метод UnSubscribeOnTimeChange для нашей формы.
В этом методе мы находим нашу форму среди подписчиков и удаляем ее вместе с ее обработчиком, чтобы потом не столкнуться с AccessViolation.