| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > Delphi: WinAPI и системное программирование > Использование RegisterWaitForSingleObject |
| Автор: Riply 29.3.2007, 22:45 |
| Здравствуйте ! Задача такая: отслеживать неоднократное "срабатывание" большого кол-ва объектов. Пытаюсь воспользоваться сабжевой функцией и (как всегда) встречаю проблемы. Допустим, мы решили поступить так: Вызываем ее с неким флагом (не WT_EXECUTEINWAITTHREAD т.к. CallBack может занять некоторое время), и с CallBack, примерно такого вида: procedure WaitObjectCallBack(pParam: Pointer; TimerOrWaitFired: Boolean); stdcall; begin with PWaitThreadParam(pParam)^ do // WaitThreadParam - нами определенная стуктура. try ResetEvent(hEvent); // Здесь hEvent - Handle нашего события, которого ждали. Этот вариант плох тем, что WaitObjectCallBack может быть вызвана 138 раз, прежде чем мы успеем вызвать ResetEvent. Вариант второй: Вызываем ее с флагом WT_EXECUTEONLYONCE. Здесь все работает, но есть очень большое "но". После каждого удачного вызова WaitObjectCallBack, мы должны снимать регистрацию нашего события ( UnregisterWait ) и заново его регистрировать. А мне кажется, что это вряд ли способствует оптимальному использованию ресурсов Как бы исхитриться и остановиться на первом варианте, но с одним вызовом WaitObjectCallBack для каждого срабатывания нашего события ? P.S. Создать некий индикатор "повторности вызова" и проверять его - (как мне кажется) не выход. |
| Автор: bems 30.3.2007, 00:19 |
| Трудно понять чего именно ты хочешь, но прискну предположить что тебе поможет событие с автосбросом. Тогда ResetEvent вызывается до вызова твоего калбека |
| Автор: Riply 30.3.2007, 01:11 |
| > bems >"Трудно понять чего именно ты хочешь" К сожалению, мои объяснения часто получаются сумбурными. :( Попробую еще раз. Есть n объектов. Их количество в процессе работы меняется и может оказаться больше чем MAXIMUM_WAIT_OBJECTS. Нужно при "срабатывании" любого из них, например, активизировать нить для обработки(или напрямую что-то выполнить) и вернуться к ожиданию. Как мне кажется, что RegisterWaitForSingleObject подходит для этого. "Автосбрасываемый" Event - решение хорошее, но, в данном случае, не подходит :( Т.к. WaitForMultipleObjects, которая внутри RegisterWaitForSingleObject, (точнее одна из них) может не успеть сработать. Например, если в данный момент времени "основная" нить RegisterWaitForSingleObject, чем-то занята. |
| Автор: Riply 30.3.2007, 16:05 |
| Большое спасибо за детальные разъяснеия. После них, многое встало на свои места. P.S. Очередной раз вынуждена признать, что утверждение "подумать - иногда, не вредно" - истинно |
| Автор: bems 31.3.2007, 00:37 | ||
| ой... за это извини, мне очень стыдно...
Добавлено через 6 минут и 57 секунд Хоть помогло? Если проблемы продолжаются - дай больше кода, разберемся по контексту, а вдруг че и придумаем... |
| Автор: Riply 31.3.2007, 02:41 | ||||||||
bems,
"К иcкусству, котрое я в данный момент представляю, это не имеет никакого отношения" (с) (Иван Васильевич меняет профессию).
Да. Спасибо. Как ни странно, но работает. Бывает же
Пока нерешаемых самостоятельно не возникло, но пользуясь случаем, вдогонку, еще один вопрос: После окончания работы с пулом (окончание - все, что надо отловили, все объекты "сняли с регистрации"), остается "висеть" несколько нитей (количество зависит от интенсивности работы пула и кол-ва объектов). Существует ли способ их завершить ? Или часть из них так и останется до завершения процесса ? P.S. Не варварским способом типа TerminateThread, а объяснить системе, что они больше не нужны |
| Автор: bems 31.3.2007, 03:09 |
| После вызова UnregisterWait/UnregisterWaitEx остаются? Тогда наверное это запас на будущее или не завершенный "естественным" путем колбэк тогда уж не знаю... |
| Автор: Riply 31.3.2007, 23:50 | ||
UnregisterWaitEx вызывался параметром INVALID_HANDLE_VALUE В "колбэке" только Sleep(10); Кроме одного исчезают минут через пять. Будем считать что система очень запаслива Еще раз спаибо. |