View Full Version : Symbian, наследник CActive с автоинициализацией
Есть задача: сделать фунцкию, выполняющуюся по изменению статуса у системного объекта. Т.е. нужна асинхронная передача управления.
Прототип: вместо системного объекта взят таймер ожидания User::After().
Реализация: на базе наследника класса CActive.
Подробности: Активный объект в конструкторе само-активируется. В методе RunL() вызывается метод обсервера и производится ре-активация.
Проблема: Не зависимо от количества выполненных итераций методом RunL() программа вылетает через ~19.5 секунд после активации активного объекта. Ошибка при вылете: Panic ViewServ 11.
Исходники проекта (без воркспейса) приложены.
Основные элементы:
1. Активный объект - class GsmInfoEngine
2. Обсервер - class GsmInfoContainer
Где я что забыл? Может, надо запрос на выполнение как-нибудь еще освобождать?
Лазание по инету не дало результатов в плане поиска работающего примера активного объекта, эмулирующего поток.
Есть задача: сделать фунцкию, выполняющуюся по изменению статуса у системного объекта. Т.е. нужна асинхронная передача управления.
Прототип: вместо системного объекта взят таймер ожидания User::After().
Реализация: на базе наследника класса CActive.
Здравствуйте,
пока не глядел в Ваши исходники. Хотелось бы понять в принципе, что за задачу Вы решаете, и какой подход к её решению используете.
Вот условие, я так понял: "Есть задача: сделать фунцкию, выполняющуюся по изменению статуса у системного объекта."
Если никаких дополнительных требований не ставится, то Ваш подход мне не понятен.
Объект А, на изменение состояния которого должен реагировать объект В, должен предоставлять call-back интерфейс, которому и должен наследовать В. Условием вызова методов этого интерфейса должно являться изменение состояния А. Такой интерфейс называют обсервером, то бишь наблюдателем. Объект-наблюдатель В, должен реализовать этот интерфейс, то есть определить свою реакцию на изменение состояния объекта А.
Объясните пожалуйста, при чём тут активные объекты?
С уважением.
Объясните пожалуйста, при чём тут активные объекты?
У объекта RBasicGsmPhone вызывается метод SignalStrengthNotification. Как только сила сигнала будет обновлена, то соответствующий запрос будет иметь статус завершенного. Active object будет отслеживать изменение статуса.
То же самое я делал и без активных объектов, например по нажатию клавиши. Но хочу, чтобы это ожидание и обновление внутренних параметров программы выполнялись автоматически и не блокировали систему.
Может есть другой способ отследить событие обновления уровня сигнала?
Или, что тоже важно, отследить событие переключения на новую соту?
Но, на данный момент, меня интересует больше всего практическая реализация активного объекта. Основная проблема: почему не работает? Поискать другие пути тоже можно, но хотелось бы решить вариант с активными объектами, чтобы подобная проблема не возникла в будущем.
В принципе, задача стоит следующим образом:
Создать и запустить поток или периодическое выполнение какого-то метода, который будет обновлять внутренние параметры программы и при необходимости выполнять перерисовку дисплея. Поток должен запускаться автоматически при старте программы. Период выполнения метода определяется не жестким интервалом, а внутренними условиями программы. Между циклами выполнения метода управление должно передаваться другим событиям, стоящим в очереди на обработку.
У объекта RBasicGsmPhone вызывается метод SignalStrengthNotification. Как только сила сигнала будет обновлена, то соответствующий запрос будет иметь статус завершенного. Active object будет отслеживать изменение статуса.
Здравствуйте.
Уже понятнее. Давайте задачу решать последовательно, не сваливая в кучу всё что нужно и ненужно.
Вот у вас есть RBasicGSMPhone - это клиентский интерфейс к серверу, который уведомляет своих клиентов о наступлении каких то событий. Другими словами, это тот самый обсервер-интерфейс. Далее, ваш клиент должен установить соединение с сервером, вызвать что то типа RBasicGSMPhone::ConnectL, проверить, что всё прошло ОК, и подписаться на приём уведомлений, то есть стать обсервером. Для этого клиент вызывает функцию RBasicGSMPhone::SignalStrengthNotification. Далее, по наступлении события, на которое Вы подписались, у Вашего клиента должно вызваться что то типа RBasicGSMPhone::SignalStrengthChanged. Эту функию Вы должны определить сами в клиенте, именно в неё придёт уведомление, и необходимые данные.
Всё ещё нет места для активных объектов, которые Вам так хочется поиспользовать :)
Не совсем понятно, почему "Как только сила сигнала будет обновлена, то соответствующий запрос будет иметь статус завершенного". Разве метод RBasicGSMPhone::SignalStrengthNotification асинхронный? Имеет он в параметрах аргумент TRequestStatus? Это было бы странно.
Асинхронным мог бы быть метод, напимер RBasicGSMPhone::GetSignalStrength(TRequestStatus aStatus, ...), в случае, если он требует значительного времени для отработки. Вот тогда, Ваш клиент-активный объект, передаёт в этом методе свой TRequestSatus, унаследованный от CActive, и сразу после вызова асинхронного метода, устанавливает его значение в ERequestPending, вызывая CActive::SetActive(). Ваш клиент после этого не ждёт выполнения запроса, а продолжает работу. После же отработки запроса, сервер меняет переданный вами статус на ERequestCompleted, на что фреймворк вызывает CActive::RunL вашего клиента, где Вы и обрабатываете результат, например, вызываете SignalChanged своего приложения.
Оцените ещё раз на концептуальном уровне ваше решение, не углубляйтесь в детали, просто найдите ключевые логические повороты в Вашей задаче. Я всё ещё не глядел в Ваш код. Хочется сначала понять способ, которым Вы решаете задачу. Пока ещё не понял:) Наверное, туп. Удачи.
Разве метод RBasicGSMPhone::SignalStrengthNotification асинхронный? Имеет он в параметрах аргумент TRequestStatus? Это было бы странно.
Асинхронным мог бы быть метод, напимер RBasicGSMPhone::GetSignalStrength(TRequestStatus aStatus, ...)
Именно, есть и имеет. Я про метод RBasicGSMPhone::SignalStrengthNotification.
А метод RBasicGSMPhone::GetSignalStrength, хоть и является асинхронным, но не ожидает обновления сигнала, а асинхронно возвращает его текущее значение, которое получено на момент вызова метода. Также есть синхронная реализация метода RBasicGSMPhone::GetSignalStrength.
Оцените ещё раз на концептуальном уровне ваше решение, не углубляйтесь в детали, просто найдите ключевые логические повороты в Вашей задаче. Я всё ещё не глядел в Ваш код. Хочется сначала понять способ, которым Вы решаете задачу.
На данный момент я решаю тривиальную задачу создания эмуляции не блокирующего программного потока в среде Симбиан.
... Хочется сначала понять способ, которым Вы решаете задачу. Пока ещё не понял:) Наверное, туп. Удачи.
ну что ты господи... не хочется человеку простых коллбаков, хочется непременно сигналов... а ты все "понят способ", "понять способ" :)
Именно, есть и имеет. Я про метод RBasicGSMPhone::SignalStrengthNotification.
А метод RBasicGSMPhone::GetSignalStrength, хоть и является асинхронным, но не ожидает обновления сигнала, а асинхронно возвращает его текущее значение, которое получено на момент вызова метода. Также есть синхронная реализация метода RBasicGSMPhone::GetSignalStrength.
Хорошо, предположим, что RBasicGSMPhone::SignalStrengthNotification асинхронный. Это говорит лишь о том, что момент возврата из него не определён. Правильным было бы прочитать спецификацию на этот метод, чтобы понять что он делает. Пока, итуитивно, мне его название говорит о том, что вызовом этого метода клиенты подписываются на получение уведомлений по поводу силы сигнала. То, что он асинхронный, ещё не обязывает вызывать его из активного объекта. Не могли бы Вы привести на этот метод документацию, это прояснит его суть. Но из задачи, которую Вы решаете, следует, что лучшим решением всё же было бы сделать клиента активным объектом.
Метод же RBasicGSMPhone::GetSignalStrength не должен ожидать обновления сигнала. С чего Вы это взяли? Он делает именно то, что должен, возвращает силу сигнала, правильную на какой то момент между вызовом этого метода и моментом возврата из него значения, если реализация не врёт. А то что он асинхронный, говорит лишь о том, что он похоже довольно ёмкий по времени.
Удачи.
Метод же RBasicGSMPhone::GetSignalStrength не должен ожидать обновления сигнала. С чего Вы это взяли? Он делает именно то, что должен, возвращает силу сигнала, правильную на какой то момент между вызовом этого метода и моментом возврата из него значения, если реализация не врёт. А то что он асинхронный, говорит лишь о том, что он похоже довольно ёмкий по времени.
Удачи.
Я понял ваши описания по поводу трансляции RequestStatus. Спасибо большое!
Метод RBasicGSMPhone::GetSignalStrength не ожидает обновления, ну... просто потому что он не ожидает ;) Он выполняется сразу же и время выполнения асинхронного запроса значительно меньше, чем при вызове GetSignalStrengthNotification. Именно оценка временной задержки и знание примерного интервала обновления уровня сигнала в режиме ожидания позволяет мне судить о том, какой из методов дает более современную информацию.
Я понял ваши описания по поводу трансляции RequestStatus. Спасибо большое!
Метод RBasicGSMPhone::GetSignalStrength не ожидает обновления, ну... просто потому что он не ожидает ;) Он выполняется сразу же и время выполнения асинхронного запроса значительно меньше, чем при вызове GetSignalStrengthNotification. Именно оценка временной задержки и знание примерного интервала обновления уровня сигнала в режиме ожидания позволяет мне судить о том, какой из методов дает более современную информацию.
Не за что. Иногда объяснение другим нетривиальных вещей делает их более понятными для самого себя.
С RBasicGSMPhone::GetSignalStrength более менее ясно.
Вы приводите новый метод RBasicGSMPhone::GetSignalStrengthNotification. Что это? Раньше Вы писали про RBasicGSMPhone::SignalStrengthNotification. Нашли Вы на него документацию? Всё же у меня сильные подозрения, что он не для извлечения силы сигнала, и не call-back, а просто подписка на уведомления. Давайте проясним, тогда сможем двигаться дальше.
Удачи.
С RBasicGSMPhone::GetSignalStrength более менее ясно.
Вы приводите новый метод RBasicGSMPhone::GetSignalStrengthNotification.
Ошибся. Это ссылка на метод RBasicGSMPhone::SignalStrengthNotification
[russian.fi, 2002-2014]