Здравствуйте! Прошу поделиться соображениями по такому вопросу.
Один из рабочих потоков главного приложения использует DLL. Библиотека собственной разработки, хорошо отлажена и функции гарантированно работают. Но вот допустим, библиотека сторонняя. Как быть, если работа ее функции зависла? Допустим, используем inproc COM сервер, вызываем метод интерфейса, и он завис. Что в таком случае делать?
Что-то я не понял... как это выносить в отдельный процесс? Приложению нужен определенный функционал, который реализован в библиотеке (или попросить у разработчиков написать вместо нее exe-шник?!). Рабочий поток приложения может зависнуть, если dll не вернет управление. Вот мне и интересны варианты "что делать" в этом случае.
У меня пока только один. Условиться о максимальном времени работы функции в библиотеке, и если оно истекло, значит произошло зависание, и нужно выгрузить библиотеку и завершить рабочий поток.
Но нужны идеи получше...
Здравствуйте, agendus, Вы писали:
A>Что-то я не понял... как это выносить в отдельный процесс? Приложению нужен определенный функционал, который реализован в библиотеке (или попросить у разработчиков написать вместо нее exe-шник?!). Рабочий поток приложения может зависнуть, если dll не вернет управление. Вот мне и интересны варианты "что делать" в этом случае. A>У меня пока только один. Условиться о максимальном времени работы функции в библиотеке, и если оно истекло, значит произошло зависание, и нужно выгрузить библиотеку и завершить рабочий поток. A>Но нужны идеи получше...
Если зависло — уже ничего не поделаешь.
Тут либо действительно выносить работу с это библиотекой в отдельный процесс (коммуникацию с ним осуществлять, допустим по пайпе) и по таймауту определять зависание, либо забивать на зависший поток и создавать новый (ну или не создавать, а обработать ошибку по другому). TerminateThread делать не рекомендуется, по соображениям приведенным в MSDN в описании этой ф-ии, а выгружать библиотеку, пока исполняется ее код — опасно, вдруг не намертво зависло.
A>Что-то я не понял... как это выносить в отдельный процесс? Приложению нужен определенный функционал, который реализован в библиотеке (или попросить у разработчиков написать вместо нее exe-шник?!). Очень просто — делаете процесс-враппер который юзает весь етот фунцкионал из библиотеки и общается с вашим основным процессом по IPC
Как много веселых ребят, и все делают велосипед...
Здравствуйте, agendus, Вы писали:
A>Что-то я не понял... как это выносить в отдельный процесс? Приложению нужен определенный функционал, который реализован в библиотеке (или попросить у разработчиков написать вместо нее exe-шник?!). Рабочий поток приложения может зависнуть, если dll не вернет управление. Вот мне и интересны варианты "что делать" в этом случае.
Если речь идет о COM, то в большинстве случаев (если есть tlb, например) перейти с inproc к local server можно без помощи разработчиков. Вызовы, конечно, на порядок медленнее работать будут.
A>У меня пока только один. Условиться о максимальном времени работы функции в библиотеке, и если оно истекло, значит произошло зависание, и нужно выгрузить библиотеку и завершить рабочий поток.
Ну-ну. Попробуй это сделать корректно
A>Но нужны идеи получше...
Не использовать чужие стремные dll вообще
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Здравствуйте, Тот кто сидит в пруду, Вы писали:
ТКС>Не использовать чужие стремные dll вообще
Они не обязательно стремные и не всегда есть выбор Имею примерно такой сценарий : приложение пытаеться автоматизировать запущеный инстанс интернет эксплорера из вне. Эксплорер подвис на какое-то время, соответстенно любое обращение к COM-у эксплорера приводит к завесу вызывающего потока, если вызывающее приложение приложение MFC то до кучи получаем диалог "Server buzy". Прибить эксплорер не могу, он конце концов проснется.
То-же самое касается не только эксплорера, а практически любого приложения с возможность внешней автоматизации( офис, SAP gui, различные terminal emulation и т.п.). Пока решение такое: прежде чем обратиться к COM-у автоматизируемого приложения посылаю его окну SendMessageTimeout(hWnd,WM_NULL ...,100), если получаю timeout то COM пока лучше не трогать, приложение скорее всего в состоянии buzy. Конечно не панацея, но таким образом значительно понижается вероятность подвисания вызывающего потока. Хотелось бы услышать предложения как решить подобную проблему другими способами и более надежно.
Здравствуйте, alexey_ma, Вы писали:
ТКС>>Не использовать чужие стремные dll вообще _>Они не обязательно стремные и не всегда есть выбор Имею примерно такой сценарий : приложение пытаеться автоматизировать запущеный инстанс интернет эксплорера из вне. Эксплорер подвис на какое-то время, соответстенно любое обращение к COM-у эксплорера приводит к завесу вызывающего потока, если вызывающее приложение приложение MFC то до кучи получаем диалог "Server buzy". Прибить эксплорер не могу, он конце концов проснется.
Ну повис и повис, жди раз ничего делать не можешь. А MFC просто предоставляет дефолтную реализацию IMessageFilter, при желании без особого труда ее можно реализовать самому. Кроме показа диалога, там можно вообще вызов "отменить" Никто правда не обещает, что COM-серверу от этого не поплохеет
_>То-же самое касается не только эксплорера, а практически любого приложения с возможность внешней автоматизации( офис, SAP gui, различные terminal emulation и т.п.). Пока решение такое: прежде чем обратиться к COM-у автоматизируемого приложения посылаю его окну SendMessageTimeout(hWnd,WM_NULL ...,100), если получаю timeout то COM пока лучше не трогать, приложение скорее всего в состоянии buzy. Конечно не панацея, но таким образом значительно понижается вероятность подвисания вызывающего потока. Хотелось бы услышать предложения как решить подобную проблему другими способами и более надежно.
Пока не понимаю, для решения какой проблемы все эти ухищрения. Ну занято целевое приложение, и что? Что планируется делать в случае таймаута? Рисовать свой диалог "приложение занято"? А смысл?
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
ТКС>Пока не понимаю, для решения какой проблемы все эти ухищрения. Ну занято целевое приложение, и что? Что планируется делать в случае таймаута? Рисовать свой диалог "приложение занято"? А смысл?
Что за привычка смотреть на все с точки зрения программера. Смысл в том чтобы предоставить юзеру сделать отмену операции. Может быть она ему совершенно не важна, но позарез требуется выполнить какую нить другую операцию с программой, которая выполнится шустро.
Никогда в студии по ошибке F1 не нажимали на самом интересном месте и на не самом шустром компе? Не возникало при этом непреодолимого желания позвонить разработчикам и попросить сделать кнопку "Отмена загрузки хелпа" ?
Как много веселых ребят, и все делают велосипед...
Здравствуйте, ononim, Вы писали:
ТКС>>Пока не понимаю, для решения какой проблемы все эти ухищрения. Ну занято целевое приложение, и что? Что планируется делать в случае таймаута? Рисовать свой диалог "приложение занято"? А смысл? O>Что за привычка смотреть на все с точки зрения программера.
Работа такая. Когда просят достать луну с неба — надо уметь аргументированно отказать
O>Смысл в том чтобы предоставить юзеру сделать отмену операции. Может быть она ему совершенно не важна, но позарез требуется выполнить какую нить другую операцию с программой, которая выполнится шустро.
В общем случае эта задача (отмена произвольного действия в произвольно взятом стороннем компоненте) не решается. Т.е., отменить-то во многих случаях можно, но вот что после этого произойдет с компонентом, никто не знает В общем случае состояние компонента может стать inconsistent, и через пару действий он просто упадет. Если потеря состояния вас устраивает, запускайте компонент как local server и срубайте время от времени.
O>Никогда в студии по ошибке F1 не нажимали на самом интересном месте и на не самом шустром компе? Не возникало при этом непреодолимого желания позвонить разработчикам и попросить сделать кнопку "Отмена загрузки хелпа" ?
Я вообще MSDN обычно отдельно запускаю
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Здравствуйте, Тот кто сидит в пруду, Вы писали:
ТКС>Ну повис и повис, жди раз ничего делать не можешь. А MFC просто предоставляет дефолтную реализацию IMessageFilter, при желании без особого труда ее можно реализовать самому. Кроме показа диалога, там можно вообще вызов "отменить" Никто правда не обещает, что COM-серверу от этого не поплохеет
Про MFC диалог я в курсе.
_>>То-же самое касается не только эксплорера, а практически любого приложения с возможность внешней автоматизации( офис, SAP gui, различные terminal emulation и т.п.). Пока решение такое: прежде чем обратиться к COM-у автоматизируемого приложения посылаю его окну SendMessageTimeout(hWnd,WM_NULL ...,100), если получаю timeout то COM пока лучше не трогать, приложение скорее всего в состоянии buzy. Конечно не панацея, но таким образом значительно понижается вероятность подвисания вызывающего потока. Хотелось бы услышать предложения как решить подобную проблему другими способами и более надежно.
ТКС>Пока не понимаю, для решения какой проблемы все эти ухищрения. Ну занято целевое приложение, и что? Что планируется делать в случае таймаута? Рисовать свой диалог "приложение занято"? А смысл?
Mercury для QA видели? Там нечто похожее.
Задача обычная для приложений автоматизации. То есть реализуется некая бизнесс логика в зависимости от состояния целевого приложения ( или нескольких приложений). Что-там будет делать бизнесс-проектировщик в случае таймаута мне неизвестно, моя задача в общем случае, приконнектиться к приложению-жертве, мониторить его состояние и уведомлять модуль бизнесс-логики о том что состояние изменилось.
Проблема именно в том как корректно узнать что целевое приложение занято, и как в случае необходимости коректно прервать подвисший вызов СОМ-а.
Дело в том что эксплорер это пример несколько надуманный поскольку я могу подписатся на эвенты браузера/доков/элементов( то есть работать event-driven) что снимает часть проблем. Но есть сервера которые не имеют ConnectionPoint, тогда приходится переодически опрашивать их состояние по таймеру и есть вероятность влипнуть в подвисший СОМ. Кроме того бизнес-логика тоже может активно воздействовать на целевое приложение, то есть вызывать какие-то методы сервера и в этом случае если сервер занят будет подвисание.
Здравствуйте, alexey_ma, Вы писали:
ТКС>>Пока не понимаю, для решения какой проблемы все эти ухищрения. Ну занято целевое приложение, и что? Что планируется делать в случае таймаута? Рисовать свой диалог "приложение занято"? А смысл? _>Mercury для QA видели? Там нечто похожее.
Нет, не видел.
_>Задача обычная для приложений автоматизации. То есть реализуется некая бизнесс логика в зависимости от состояния целевого приложения ( или нескольких приложений). Что-там будет делать бизнесс-проектировщик в случае таймаута мне неизвестно, моя задача в общем случае, приконнектиться к приложению-жертве, мониторить его состояние и уведомлять модуль бизнесс-логики о том что состояние изменилось.
Я сомневаюсь именно в том, что вышеприведенное — осмысленный сценарий поведения, по крайней мере в отсутствии жесткого расписания. Вся "бизнесс логика" в случае подвисания одного контролируемого приложения обычно сводится к разного рода прогресс-барам и часикам. Грубо говоря, если вы можете не делать какое-то действие в случае подвисания — то может лучше его не делать никогда?
_>Проблема именно в том как корректно узнать что целевое приложение занято, и как в случае необходимости коректно прервать подвисший вызов СОМ-а.
В общем случае — никак, разумеется, не узнать. Подвисший COM-вызов иногда можно прервать, вернув PENDINGMSG_CANCELCALL из IMessageFilter::MessagePending. Но полной корректности никто, естественно, не обещает.
_>Дело в том что эксплорер это пример несколько надуманный поскольку я могу подписатся на эвенты браузера/доков/элементов( то есть работать event-driven) что снимает часть проблем. Но есть сервера которые не имеют ConnectionPoint, тогда приходится переодически опрашивать их состояние по таймеру и есть вероятность влипнуть в подвисший СОМ. Кроме того бизнес-логика тоже может активно воздействовать на целевое приложение, то есть вызывать какие-то методы сервера и в этом случае если сервер занят будет подвисание.
Ну будет подвисание, и что? Большая что ли проблема вынести GUI в одну нить, COM — в другой?
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Здравствуйте, Тот кто сидит в пруду, Вы писали:
_>>Mercury для QA видели? Там нечто похожее. ТКС>Нет, не видел.
Весьма мощное приложения для автоматического тестирования приложений.
_>>Задача обычная для приложений автоматизации. То есть реализуется некая бизнесс логика в зависимости от состояния целевого приложения ( или нескольких приложений). Что-там будет делать бизнесс-проектировщик в случае таймаута мне неизвестно, моя задача в общем случае, приконнектиться к приложению-жертве, мониторить его состояние и уведомлять модуль бизнесс-логики о том что состояние изменилось.
ТКС>Я сомневаюсь именно в том, что вышеприведенное — осмысленный сценарий поведения, по крайней мере в отсутствии жесткого расписания. Вся "бизнесс логика" в случае подвисания одного контролируемого приложения обычно сводится к разного рода прогресс-барам и часикам. Грубо говоря, если вы можете не делать какое-то действие в случае подвисания — то может лучше его не делать никогда?
Я об этом и говорю, я мне хотелось бы знать что приложение-жертва не висит до того как я начну что-то делать.
А логика может быть примерно такая: если в таком-то поле ввода есть определенный текст и в таком-то комбо выбран такой-то айтем то показать юзеру тултип с таким-то текстом и выделить такую-то строку в гриде и отметить такой-то чекбокс и нажать такую-то кнопку.
Мне по любому придется когда-то выяснять что содержит поле ввода и состояние комбо. Как достоверно узнать что в момент запроса целевая аппликация не busy? Что я в этом случае буду делать не столь важно, скорее всего уведомлю модуль бизнесс-логики о невозможности получения данных и тупо повторю опрос через какое-то время.
ТКС>В общем случае — никак, разумеется, не узнать. Подвисший COM-вызов иногда можно прервать, вернув PENDINGMSG_CANCELCALL из IMessageFilter::MessagePending. Но полной корректности никто, естественно, не обещает.
В курсе. Поэтому и стараюсь избегать завесов
ТКС>Ну будет подвисание, и что? Большая что ли проблема вынести GUI в одну нить, COM — в другой?
Конечно, так и делаем.
В общем случае задача сводиться к следующему: Есть некий outproc COM сервер. Я хочу достоверно знать что он не висит( или не в длительном busy) не обращаясь к его методам, поскольку любое обращение к этим самым методам приведет к завесу( или значительной задержке) моего потока.
O>>Никогда в студии по ошибке F1 не нажимали на самом интересном месте и на не самом шустром компе? Не возникало при этом непреодолимого желания позвонить разработчикам и попросить сделать кнопку "Отмена загрузки хелпа" ?
ТКС>Я вообще MSDN обычно отдельно запускаю
Аналогично, только вот последствия случайного F1 раздражали пару раз, на второй раз надоело и прибил F1 в настройках. Но всё же
Здравствуйте, alexey_ma, Вы писали:
ТКС>>Грубо говоря, если вы можете не делать какое-то действие в случае подвисания — то может лучше его не делать никогда? _>Я об этом и говорю, я мне хотелось бы знать что приложение-жертва не висит до того как я начну что-то делать.
Видимо, не об этом.
_>А логика может быть примерно такая: если в таком-то поле ввода есть определенный текст и в таком-то комбо выбран такой-то айтем то показать юзеру тултип с таким-то текстом и выделить такую-то строку в гриде и отметить такой-то чекбокс и нажать такую-то кнопку. _>Мне по любому придется когда-то выяснять что содержит поле ввода и состояние комбо. Как достоверно узнать что в момент запроса целевая аппликация не busy? Что я в этом случае буду делать не столь важно, скорее всего уведомлю модуль бизнесс-логики о невозможности получения данных и тупо повторю опрос через какое-то время.
А зачем узнавать, что в момент запроса целевая аппликация не busy? Все равно же переспрашивать ее придется? Ну и считай, что пока не отвечает — висит. Ответил — уведомь верхний уровень.
ТКС>>Ну будет подвисание, и что? Большая что ли проблема вынести GUI в одну нить, COM — в другой? _>Конечно, так и делаем. _>В общем случае задача сводиться к следующему: Есть некий outproc COM сервер. Я хочу достоверно знать что он не висит( или не в длительном busy) не обращаясь к его методам, поскольку любое обращение к этим самым методам приведет к завесу( или значительной задержке) моего потока.
Не-не-не, все гораздо хуже. Выше сформулированная задача хотя бы теоретически может иметь решение. А на самом деле ты хочешь достоверно знать, не повиснет ли COM сервер при следующем обращении, а не в момент проверки. Что в общем случае, естественно, не решается в принципе.
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
ТКС>А зачем узнавать, что в момент запроса целевая аппликация не busy? Все равно же переспрашивать ее придется? Ну и считай, что пока не отвечает — висит. Ответил — уведомь верхний уровень.
Как узнать что сервер не отвечает без риска( ну или с минимальным риском) повесить свой поток?
ТКС>>>Ну будет подвисание, и что? Большая что ли проблема вынести GUI в одну нить, COM — в другой? _>>Конечно, так и делаем. _>>В общем случае задача сводиться к следующему: Есть некий outproc COM сервер. Я хочу достоверно знать что он не висит( или не в длительном busy) не обращаясь к его методам, поскольку любое обращение к этим самым методам приведет к завесу( или значительной задержке) моего потока.
ТКС>Не-не-не, все гораздо хуже. Выше сформулированная задача хотя бы теоретически может иметь решение. А на самом деле ты хочешь достоверно знать, не повиснет ли COM сервер при следующем обращении, а не в момент проверки. Что в общем случае, естественно, не решается в принципе.
Хорошо, как хотя-бы проверку сделать? Я не хочу делать вообще никаких обращений пока сервер висит, и только если сервер ready вызывать его методы. Есть конечно теоретическая вероятность того что сервер успеет повиснуть между проверкой на busy и последуюшим обращением, но с этим я в принципе готов смириться и попробовать прервать зависший вызов.
Здравствуйте, alexey_ma, Вы писали:
ТКС>>А зачем узнавать, что в момент запроса целевая аппликация не busy? Все равно же переспрашивать ее придется? Ну и считай, что пока не отвечает — висит. Ответил — уведомь верхний уровень. _>Как узнать что сервер не отвечает без риска( ну или с минимальным риском) повесить свой поток?
Это неправильная постановка задачи, IMHO. Правильная — писать программу так, чтобы зависший поток ничему не мешал. Вот пишу я допустим программу сетевого обмена — она постоянно ждет либо ответа/запроса из сети, либо ввода пользователя либо какого-нибудь еще события. Если сеть сразу не отвечает — ничего страшного, это штатная ситуация. Придет ответ — отреагируем.
ТКС>>>>Ну будет подвисание, и что? Большая что ли проблема вынести GUI в одну нить, COM — в другой? _>>>Конечно, так и делаем. _>>>В общем случае задача сводиться к следующему: Есть некий outproc COM сервер. Я хочу достоверно знать что он не висит( или не в длительном busy) не обращаясь к его методам, поскольку любое обращение к этим самым методам приведет к завесу( или значительной задержке) моего потока.
ТКС>>Не-не-не, все гораздо хуже. Выше сформулированная задача хотя бы теоретически может иметь решение. А на самом деле ты хочешь достоверно знать, не повиснет ли COM сервер при следующем обращении, а не в момент проверки. Что в общем случае, естественно, не решается в принципе. _>Хорошо, как хотя-бы проверку сделать? Я не хочу делать вообще никаких обращений пока сервер висит, и только если сервер ready вызывать его методы. Есть конечно теоретическая вероятность того что сервер успеет повиснуть между проверкой на busy и последуюшим обращением, но с этим я в принципе готов смириться и попробовать прервать зависший вызов.
В общем случае — никак, естественно, не сделать. Очень часто вообще нет такого понятия как ready. При одних параметрах вызова сервер будет тупить 100 мс, при других — 100 с, при третьих — вообще упадет. Поэтому никто ни каких проверок на готовность при разработке COM видимо и не предусматривал. Если все равно сильно хочется — ну можно сделать свою проксю, которая в отдельной нити будет ставить запрос в очередь, а на время выполнения выставлять читаемый клиентом флаг и на любые вызовы возвращать какой-нибудь RPC_E_RETRY. Только, IMHO, это изначально кривой путь.
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Здравствуйте, Тот кто сидит в пруду, Вы писали:
ТКС>Это неправильная постановка задачи, IMHO. Правильная — писать программу так, чтобы зависший поток ничему не мешал. Вот пишу я допустим программу сетевого обмена — она постоянно ждет либо ответа/запроса из сети, либо ввода пользователя либо какого-нибудь еще события. Если сеть сразу не отвечает — ничего страшного, это штатная ситуация. Придет ответ — отреагируем.
Не подходит. Я писал что когда есть возможность получать эвенты от сервера это совсем другая работа, там как раз все нормально. Тот же браузер например, получил эвент document ready/complete и вперед. Но такое не всегда возможно.
_>>Хорошо, как хотя-бы проверку сделать? Я не хочу делать вообще никаких обращений пока сервер висит, и только если сервер ready вызывать его методы. Есть конечно теоретическая вероятность того что сервер успеет повиснуть между проверкой на busy и последуюшим обращением, но с этим я в принципе готов смириться и попробовать прервать зависший вызов.
ТКС>В общем случае — никак, естественно, не сделать. Очень часто вообще нет такого понятия как ready. При одних параметрах вызова сервер будет тупить 100 мс, при других — 100 с, при третьих — вообще упадет. Поэтому никто ни каких проверок на готовность при разработке COM видимо и не предусматривал. Если все равно сильно хочется — ну можно сделать свою проксю, которая в отдельной нити будет ставить запрос в очередь, а на время выполнения выставлять читаемый клиентом флаг и на любые вызовы возвращать какой-нибудь RPC_E_RETRY. Только, IMHO, это изначально кривой путь.
Про прокси можно подумать. А пока мой метод с SendMessageTimeout достаточно надежно работает, только не у всех серверов есть окна . Есть еще асинхронные сервера, где в принципе можно сделать саncel запросу, но мне пока таковые не попадались.
Здравствуйте, alexey_ma, Вы писали:
ТКС>>Это неправильная постановка задачи, IMHO. Правильная — писать программу так, чтобы зависший поток ничему не мешал. Вот пишу я допустим программу сетевого обмена — она постоянно ждет либо ответа/запроса из сети, либо ввода пользователя либо какого-нибудь еще события. Если сеть сразу не отвечает — ничего страшного, это штатная ситуация. Придет ответ — отреагируем. _>Не подходит. Я писал что когда есть возможность получать эвенты от сервера это совсем другая работа, там как раз все нормально. Тот же браузер например, получил эвент document ready/complete и вперед. Но такое не всегда возможно.
Зачем события? С сетью все замечательно делается даже на обычных блокирующих операциях, следовательно, и в других случаях можно вполне жить с блокировками.
_>>>Хорошо, как хотя-бы проверку сделать? Я не хочу делать вообще никаких обращений пока сервер висит, и только если сервер ready вызывать его методы. Есть конечно теоретическая вероятность того что сервер успеет повиснуть между проверкой на busy и последуюшим обращением, но с этим я в принципе готов смириться и попробовать прервать зависший вызов.
ТКС>>В общем случае — никак, естественно, не сделать. Очень часто вообще нет такого понятия как ready. При одних параметрах вызова сервер будет тупить 100 мс, при других — 100 с, при третьих — вообще упадет. Поэтому никто ни каких проверок на готовность при разработке COM видимо и не предусматривал. Если все равно сильно хочется — ну можно сделать свою проксю, которая в отдельной нити будет ставить запрос в очередь, а на время выполнения выставлять читаемый клиентом флаг и на любые вызовы возвращать какой-нибудь RPC_E_RETRY. Только, IMHO, это изначально кривой путь. _>Про прокси можно подумать. А пока мой метод с SendMessageTimeout достаточно надежно работает, только не у всех серверов есть окна .
Вообще COM, когда я последний раз им интересовался, был реализован с использованием скрытых окон — видимо, MS было лень писать еще одну очередь сообщений. Можно попробовать с ним работать — если оно в винде еще наличествует.
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Здравствуйте, Тот кто сидит в пруду, Вы писали:
_>>Не подходит. Я писал что когда есть возможность получать эвенты от сервера это совсем другая работа, там как раз все нормально. Тот же браузер например, получил эвент document ready/complete и вперед. Но такое не всегда возможно.
ТКС>Зачем события? С сетью все замечательно делается даже на обычных блокирующих операциях, следовательно, и в других случаях можно вполне жить с блокировками.
Эвенты CОМ-а по сути те-же блокирующие операции, реализация не так уж важна, важна сама возможность получать события/уведомления о изменении состояния сервера и возможность самому инициировать cобытия на сервере. В этом случае как-раз то можно все более мене нормально сделать.
ТКС>>>В общем случае — никак, естественно, не сделать. Очень часто вообще нет такого понятия как ready. При одних параметрах вызова сервер будет тупить 100 мс, при других — 100 с, при третьих — вообще упадет. Поэтому никто ни каких проверок на готовность при разработке COM видимо и не предусматривал. Если все равно сильно хочется — ну можно сделать свою проксю, которая в отдельной нити будет ставить запрос в очередь, а на время выполнения выставлять читаемый клиентом флаг и на любые вызовы возвращать какой-нибудь RPC_E_RETRY. Только, IMHO, это изначально кривой путь. _>>Про прокси можно подумать. А пока мой метод с SendMessageTimeout достаточно надежно работает, только не у всех серверов есть окна .
ТКС>Вообще COM, когда я последний раз им интересовался, был реализован с использованием скрытых окон — видимо, MS было лень писать еще одну очередь сообщений. Можно попробовать с ним работать — если оно в винде еще наличествует.
Ага, COM STA использует скрытые окна, я очень давно пробовал пробовал их опрашивать, просто оказалось что с гуевым окном сервера проще. Мне в основном интересны сервера имеющие гуй, в этом случае перед обращением к СОМ-у еще иногда можно проверить процесс на InputIdle.