как работать с проблемной dll?
От: agendus  
Дата: 27.01.10 08:37
Оценка:
Здравствуйте! Прошу поделиться соображениями по такому вопросу.
Один из рабочих потоков главного приложения использует DLL. Библиотека собственной разработки, хорошо отлажена и функции гарантированно работают. Но вот допустим, библиотека сторонняя. Как быть, если работа ее функции зависла? Допустим, используем inproc COM сервер, вызываем метод интерфейса, и он завис. Что в таком случае делать?
Re: как работать с проблемной dll?
От: ononim  
Дата: 27.01.10 08:58
Оценка:
Выносить ее в отдельный процесс который можно будет смело убить (если конечно от этого не порушится что нить еще).
Как много веселых ребят, и все делают велосипед...
Re[2]: как работать с проблемной dll?
От: agendus  
Дата: 27.01.10 09:11
Оценка:
Что-то я не понял... как это выносить в отдельный процесс? Приложению нужен определенный функционал, который реализован в библиотеке (или попросить у разработчиков написать вместо нее exe-шник?!). Рабочий поток приложения может зависнуть, если dll не вернет управление. Вот мне и интересны варианты "что делать" в этом случае.
У меня пока только один. Условиться о максимальном времени работы функции в библиотеке, и если оно истекло, значит произошло зависание, и нужно выгрузить библиотеку и завершить рабочий поток.
Но нужны идеи получше...
Re[3]: как работать с проблемной dll?
От: brain-ripper  
Дата: 27.01.10 09:20
Оценка:
Здравствуйте, agendus, Вы писали:

A>Что-то я не понял... как это выносить в отдельный процесс? Приложению нужен определенный функционал, который реализован в библиотеке (или попросить у разработчиков написать вместо нее exe-шник?!). Рабочий поток приложения может зависнуть, если dll не вернет управление. Вот мне и интересны варианты "что делать" в этом случае.

A>У меня пока только один. Условиться о максимальном времени работы функции в библиотеке, и если оно истекло, значит произошло зависание, и нужно выгрузить библиотеку и завершить рабочий поток.
A>Но нужны идеи получше...


Если зависло — уже ничего не поделаешь.
Тут либо действительно выносить работу с это библиотекой в отдельный процесс (коммуникацию с ним осуществлять, допустим по пайпе) и по таймауту определять зависание, либо забивать на зависший поток и создавать новый (ну или не создавать, а обработать ошибку по другому). TerminateThread делать не рекомендуется, по соображениям приведенным в MSDN в описании этой ф-ии, а выгружать библиотеку, пока исполняется ее код — опасно, вдруг не намертво зависло.
Re[3]: как работать с проблемной dll?
От: ononim  
Дата: 27.01.10 09:26
Оценка:
A>Что-то я не понял... как это выносить в отдельный процесс? Приложению нужен определенный функционал, который реализован в библиотеке (или попросить у разработчиков написать вместо нее exe-шник?!). Очень просто — делаете процесс-враппер который юзает весь етот фунцкионал из библиотеки и общается с вашим основным процессом по IPC
Как много веселых ребят, и все делают велосипед...
Re[3]: как работать с проблемной dll?
От: Тот кто сидит в пруду Россия  
Дата: 27.01.10 09:35
Оценка:
Здравствуйте, agendus, Вы писали:

A>Что-то я не понял... как это выносить в отдельный процесс? Приложению нужен определенный функционал, который реализован в библиотеке (или попросить у разработчиков написать вместо нее exe-шник?!). Рабочий поток приложения может зависнуть, если dll не вернет управление. Вот мне и интересны варианты "что делать" в этом случае.


Если речь идет о COM, то в большинстве случаев (если есть tlb, например) перейти с inproc к local server можно без помощи разработчиков. Вызовы, конечно, на порядок медленнее работать будут.

A>У меня пока только один. Условиться о максимальном времени работы функции в библиотеке, и если оно истекло, значит произошло зависание, и нужно выгрузить библиотеку и завершить рабочий поток.


Ну-ну. Попробуй это сделать корректно

A>Но нужны идеи получше...


Не использовать чужие стремные dll вообще
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Re[4]: как работать с проблемной dll?
От: alexey_ma Израиль  
Дата: 27.01.10 11:52
Оценка:
Здравствуйте, Тот кто сидит в пруду, Вы писали:

ТКС>Не использовать чужие стремные dll вообще

Они не обязательно стремные и не всегда есть выбор Имею примерно такой сценарий : приложение пытаеться автоматизировать запущеный инстанс интернет эксплорера из вне. Эксплорер подвис на какое-то время, соответстенно любое обращение к COM-у эксплорера приводит к завесу вызывающего потока, если вызывающее приложение приложение MFC то до кучи получаем диалог "Server buzy". Прибить эксплорер не могу, он конце концов проснется.
То-же самое касается не только эксплорера, а практически любого приложения с возможность внешней автоматизации( офис, SAP gui, различные terminal emulation и т.п.). Пока решение такое: прежде чем обратиться к COM-у автоматизируемого приложения посылаю его окну SendMessageTimeout(hWnd,WM_NULL ...,100), если получаю timeout то COM пока лучше не трогать, приложение скорее всего в состоянии buzy. Конечно не панацея, но таким образом значительно понижается вероятность подвисания вызывающего потока. Хотелось бы услышать предложения как решить подобную проблему другими способами и более надежно.
Re[5]: как работать с проблемной dll?
От: Тот кто сидит в пруду Россия  
Дата: 27.01.10 12:05
Оценка:
Здравствуйте, alexey_ma, Вы писали:

ТКС>>Не использовать чужие стремные dll вообще

_>Они не обязательно стремные и не всегда есть выбор Имею примерно такой сценарий : приложение пытаеться автоматизировать запущеный инстанс интернет эксплорера из вне. Эксплорер подвис на какое-то время, соответстенно любое обращение к COM-у эксплорера приводит к завесу вызывающего потока, если вызывающее приложение приложение MFC то до кучи получаем диалог "Server buzy". Прибить эксплорер не могу, он конце концов проснется.

Ну повис и повис, жди раз ничего делать не можешь. А MFC просто предоставляет дефолтную реализацию IMessageFilter, при желании без особого труда ее можно реализовать самому. Кроме показа диалога, там можно вообще вызов "отменить" Никто правда не обещает, что COM-серверу от этого не поплохеет

_>То-же самое касается не только эксплорера, а практически любого приложения с возможность внешней автоматизации( офис, SAP gui, различные terminal emulation и т.п.). Пока решение такое: прежде чем обратиться к COM-у автоматизируемого приложения посылаю его окну SendMessageTimeout(hWnd,WM_NULL ...,100), если получаю timeout то COM пока лучше не трогать, приложение скорее всего в состоянии buzy. Конечно не панацея, но таким образом значительно понижается вероятность подвисания вызывающего потока. Хотелось бы услышать предложения как решить подобную проблему другими способами и более надежно.


Пока не понимаю, для решения какой проблемы все эти ухищрения. Ну занято целевое приложение, и что? Что планируется делать в случае таймаута? Рисовать свой диалог "приложение занято"? А смысл?
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Re[6]: как работать с проблемной dll?
От: ononim  
Дата: 27.01.10 12:12
Оценка: +1 :)
ТКС>Пока не понимаю, для решения какой проблемы все эти ухищрения. Ну занято целевое приложение, и что? Что планируется делать в случае таймаута? Рисовать свой диалог "приложение занято"? А смысл?
Что за привычка смотреть на все с точки зрения программера. Смысл в том чтобы предоставить юзеру сделать отмену операции. Может быть она ему совершенно не важна, но позарез требуется выполнить какую нить другую операцию с программой, которая выполнится шустро.
Никогда в студии по ошибке F1 не нажимали на самом интересном месте и на не самом шустром компе? Не возникало при этом непреодолимого желания позвонить разработчикам и попросить сделать кнопку "Отмена загрузки хелпа" ?
Как много веселых ребят, и все делают велосипед...
Re[7]: как работать с проблемной dll?
От: Тот кто сидит в пруду Россия  
Дата: 27.01.10 12:21
Оценка: 1 (1)
Здравствуйте, ononim, Вы писали:

ТКС>>Пока не понимаю, для решения какой проблемы все эти ухищрения. Ну занято целевое приложение, и что? Что планируется делать в случае таймаута? Рисовать свой диалог "приложение занято"? А смысл?

O>Что за привычка смотреть на все с точки зрения программера.

Работа такая. Когда просят достать луну с неба — надо уметь аргументированно отказать

O>Смысл в том чтобы предоставить юзеру сделать отмену операции. Может быть она ему совершенно не важна, но позарез требуется выполнить какую нить другую операцию с программой, которая выполнится шустро.


В общем случае эта задача (отмена произвольного действия в произвольно взятом стороннем компоненте) не решается. Т.е., отменить-то во многих случаях можно, но вот что после этого произойдет с компонентом, никто не знает В общем случае состояние компонента может стать inconsistent, и через пару действий он просто упадет. Если потеря состояния вас устраивает, запускайте компонент как local server и срубайте время от времени.

O>Никогда в студии по ошибке F1 не нажимали на самом интересном месте и на не самом шустром компе? Не возникало при этом непреодолимого желания позвонить разработчикам и попросить сделать кнопку "Отмена загрузки хелпа" ?


Я вообще MSDN обычно отдельно запускаю
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Re[6]: как работать с проблемной dll?
От: alexey_ma Израиль  
Дата: 27.01.10 13:24
Оценка:
Здравствуйте, Тот кто сидит в пруду, Вы писали:

ТКС>Ну повис и повис, жди раз ничего делать не можешь. А MFC просто предоставляет дефолтную реализацию IMessageFilter, при желании без особого труда ее можно реализовать самому. Кроме показа диалога, там можно вообще вызов "отменить" Никто правда не обещает, что COM-серверу от этого не поплохеет

Про MFC диалог я в курсе.

_>>То-же самое касается не только эксплорера, а практически любого приложения с возможность внешней автоматизации( офис, SAP gui, различные terminal emulation и т.п.). Пока решение такое: прежде чем обратиться к COM-у автоматизируемого приложения посылаю его окну SendMessageTimeout(hWnd,WM_NULL ...,100), если получаю timeout то COM пока лучше не трогать, приложение скорее всего в состоянии buzy. Конечно не панацея, но таким образом значительно понижается вероятность подвисания вызывающего потока. Хотелось бы услышать предложения как решить подобную проблему другими способами и более надежно.


ТКС>Пока не понимаю, для решения какой проблемы все эти ухищрения. Ну занято целевое приложение, и что? Что планируется делать в случае таймаута? Рисовать свой диалог "приложение занято"? А смысл?

Mercury для QA видели? Там нечто похожее.
Задача обычная для приложений автоматизации. То есть реализуется некая бизнесс логика в зависимости от состояния целевого приложения ( или нескольких приложений). Что-там будет делать бизнесс-проектировщик в случае таймаута мне неизвестно, моя задача в общем случае, приконнектиться к приложению-жертве, мониторить его состояние и уведомлять модуль бизнесс-логики о том что состояние изменилось.
Проблема именно в том как корректно узнать что целевое приложение занято, и как в случае необходимости коректно прервать подвисший вызов СОМ-а.
Дело в том что эксплорер это пример несколько надуманный поскольку я могу подписатся на эвенты браузера/доков/элементов( то есть работать event-driven) что снимает часть проблем. Но есть сервера которые не имеют ConnectionPoint, тогда приходится переодически опрашивать их состояние по таймеру и есть вероятность влипнуть в подвисший СОМ. Кроме того бизнес-логика тоже может активно воздействовать на целевое приложение, то есть вызывать какие-то методы сервера и в этом случае если сервер занят будет подвисание.
Re[7]: как работать с проблемной dll?
От: Тот кто сидит в пруду Россия  
Дата: 27.01.10 13:45
Оценка:
Здравствуйте, alexey_ma, Вы писали:

ТКС>>Пока не понимаю, для решения какой проблемы все эти ухищрения. Ну занято целевое приложение, и что? Что планируется делать в случае таймаута? Рисовать свой диалог "приложение занято"? А смысл?

_>Mercury для QA видели? Там нечто похожее.

Нет, не видел.

_>Задача обычная для приложений автоматизации. То есть реализуется некая бизнесс логика в зависимости от состояния целевого приложения ( или нескольких приложений). Что-там будет делать бизнесс-проектировщик в случае таймаута мне неизвестно, моя задача в общем случае, приконнектиться к приложению-жертве, мониторить его состояние и уведомлять модуль бизнесс-логики о том что состояние изменилось.


Я сомневаюсь именно в том, что вышеприведенное — осмысленный сценарий поведения, по крайней мере в отсутствии жесткого расписания. Вся "бизнесс логика" в случае подвисания одного контролируемого приложения обычно сводится к разного рода прогресс-барам и часикам. Грубо говоря, если вы можете не делать какое-то действие в случае подвисания — то может лучше его не делать никогда?

_>Проблема именно в том как корректно узнать что целевое приложение занято, и как в случае необходимости коректно прервать подвисший вызов СОМ-а.


В общем случае — никак, разумеется, не узнать. Подвисший COM-вызов иногда можно прервать, вернув PENDINGMSG_CANCELCALL из IMessageFilter::MessagePending. Но полной корректности никто, естественно, не обещает.

_>Дело в том что эксплорер это пример несколько надуманный поскольку я могу подписатся на эвенты браузера/доков/элементов( то есть работать event-driven) что снимает часть проблем. Но есть сервера которые не имеют ConnectionPoint, тогда приходится переодически опрашивать их состояние по таймеру и есть вероятность влипнуть в подвисший СОМ. Кроме того бизнес-логика тоже может активно воздействовать на целевое приложение, то есть вызывать какие-то методы сервера и в этом случае если сервер занят будет подвисание.


Ну будет подвисание, и что? Большая что ли проблема вынести GUI в одну нить, COM — в другой?
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Re[8]: как работать с проблемной dll?
От: alexey_ma Израиль  
Дата: 27.01.10 15:19
Оценка:
Здравствуйте, Тот кто сидит в пруду, Вы писали:

_>>Mercury для QA видели? Там нечто похожее.

ТКС>Нет, не видел.
Весьма мощное приложения для автоматического тестирования приложений.

_>>Задача обычная для приложений автоматизации. То есть реализуется некая бизнесс логика в зависимости от состояния целевого приложения ( или нескольких приложений). Что-там будет делать бизнесс-проектировщик в случае таймаута мне неизвестно, моя задача в общем случае, приконнектиться к приложению-жертве, мониторить его состояние и уведомлять модуль бизнесс-логики о том что состояние изменилось.


ТКС>Я сомневаюсь именно в том, что вышеприведенное — осмысленный сценарий поведения, по крайней мере в отсутствии жесткого расписания. Вся "бизнесс логика" в случае подвисания одного контролируемого приложения обычно сводится к разного рода прогресс-барам и часикам. Грубо говоря, если вы можете не делать какое-то действие в случае подвисания — то может лучше его не делать никогда?

Я об этом и говорю, я мне хотелось бы знать что приложение-жертва не висит до того как я начну что-то делать.
А логика может быть примерно такая: если в таком-то поле ввода есть определенный текст и в таком-то комбо выбран такой-то айтем то показать юзеру тултип с таким-то текстом и выделить такую-то строку в гриде и отметить такой-то чекбокс и нажать такую-то кнопку.
Мне по любому придется когда-то выяснять что содержит поле ввода и состояние комбо. Как достоверно узнать что в момент запроса целевая аппликация не busy? Что я в этом случае буду делать не столь важно, скорее всего уведомлю модуль бизнесс-логики о невозможности получения данных и тупо повторю опрос через какое-то время.

ТКС>В общем случае — никак, разумеется, не узнать. Подвисший COM-вызов иногда можно прервать, вернув PENDINGMSG_CANCELCALL из IMessageFilter::MessagePending. Но полной корректности никто, естественно, не обещает.

В курсе. Поэтому и стараюсь избегать завесов

ТКС>Ну будет подвисание, и что? Большая что ли проблема вынести GUI в одну нить, COM — в другой?

Конечно, так и делаем.
В общем случае задача сводиться к следующему: Есть некий outproc COM сервер. Я хочу достоверно знать что он не висит( или не в длительном busy) не обращаясь к его методам, поскольку любое обращение к этим самым методам приведет к завесу( или значительной задержке) моего потока.
Re[8]: как работать с проблемной dll?
От: std.denis Россия  
Дата: 27.01.10 15:38
Оценка:
O>>Никогда в студии по ошибке F1 не нажимали на самом интересном месте и на не самом шустром компе? Не возникало при этом непреодолимого желания позвонить разработчикам и попросить сделать кнопку "Отмена загрузки хелпа" ?

ТКС>Я вообще MSDN обычно отдельно запускаю


Аналогично, только вот последствия случайного F1 раздражали пару раз, на второй раз надоело и прибил F1 в настройках. Но всё же
Re[9]: как работать с проблемной dll?
От: Тот кто сидит в пруду Россия  
Дата: 27.01.10 15:46
Оценка:
Здравствуйте, alexey_ma, Вы писали:

ТКС>>Грубо говоря, если вы можете не делать какое-то действие в случае подвисания — то может лучше его не делать никогда?

_>Я об этом и говорю, я мне хотелось бы знать что приложение-жертва не висит до того как я начну что-то делать.

Видимо, не об этом.

_>А логика может быть примерно такая: если в таком-то поле ввода есть определенный текст и в таком-то комбо выбран такой-то айтем то показать юзеру тултип с таким-то текстом и выделить такую-то строку в гриде и отметить такой-то чекбокс и нажать такую-то кнопку.

_>Мне по любому придется когда-то выяснять что содержит поле ввода и состояние комбо. Как достоверно узнать что в момент запроса целевая аппликация не busy? Что я в этом случае буду делать не столь важно, скорее всего уведомлю модуль бизнесс-логики о невозможности получения данных и тупо повторю опрос через какое-то время.

А зачем узнавать, что в момент запроса целевая аппликация не busy? Все равно же переспрашивать ее придется? Ну и считай, что пока не отвечает — висит. Ответил — уведомь верхний уровень.

ТКС>>Ну будет подвисание, и что? Большая что ли проблема вынести GUI в одну нить, COM — в другой?

_>Конечно, так и делаем.
_>В общем случае задача сводиться к следующему: Есть некий outproc COM сервер. Я хочу достоверно знать что он не висит( или не в длительном busy) не обращаясь к его методам, поскольку любое обращение к этим самым методам приведет к завесу( или значительной задержке) моего потока.

Не-не-не, все гораздо хуже. Выше сформулированная задача хотя бы теоретически может иметь решение. А на самом деле ты хочешь достоверно знать, не повиснет ли COM сервер при следующем обращении, а не в момент проверки. Что в общем случае, естественно, не решается в принципе.
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Re[10]: как работать с проблемной dll?
От: alexey_ma Израиль  
Дата: 27.01.10 16:25
Оценка:
Здравствуйте, Тот кто сидит в пруду, Вы писали:


ТКС>А зачем узнавать, что в момент запроса целевая аппликация не busy? Все равно же переспрашивать ее придется? Ну и считай, что пока не отвечает — висит. Ответил — уведомь верхний уровень.

Как узнать что сервер не отвечает без риска( ну или с минимальным риском) повесить свой поток?

ТКС>>>Ну будет подвисание, и что? Большая что ли проблема вынести GUI в одну нить, COM — в другой?

_>>Конечно, так и делаем.
_>>В общем случае задача сводиться к следующему: Есть некий outproc COM сервер. Я хочу достоверно знать что он не висит( или не в длительном busy) не обращаясь к его методам, поскольку любое обращение к этим самым методам приведет к завесу( или значительной задержке) моего потока.

ТКС>Не-не-не, все гораздо хуже. Выше сформулированная задача хотя бы теоретически может иметь решение. А на самом деле ты хочешь достоверно знать, не повиснет ли COM сервер при следующем обращении, а не в момент проверки. Что в общем случае, естественно, не решается в принципе.

Хорошо, как хотя-бы проверку сделать? Я не хочу делать вообще никаких обращений пока сервер висит, и только если сервер ready вызывать его методы. Есть конечно теоретическая вероятность того что сервер успеет повиснуть между проверкой на busy и последуюшим обращением, но с этим я в принципе готов смириться и попробовать прервать зависший вызов.
Re[11]: как работать с проблемной dll?
От: Тот кто сидит в пруду Россия  
Дата: 27.01.10 17:10
Оценка:
Здравствуйте, alexey_ma, Вы писали:

ТКС>>А зачем узнавать, что в момент запроса целевая аппликация не busy? Все равно же переспрашивать ее придется? Ну и считай, что пока не отвечает — висит. Ответил — уведомь верхний уровень.

_>Как узнать что сервер не отвечает без риска( ну или с минимальным риском) повесить свой поток?

Это неправильная постановка задачи, IMHO. Правильная — писать программу так, чтобы зависший поток ничему не мешал. Вот пишу я допустим программу сетевого обмена — она постоянно ждет либо ответа/запроса из сети, либо ввода пользователя либо какого-нибудь еще события. Если сеть сразу не отвечает — ничего страшного, это штатная ситуация. Придет ответ — отреагируем.

ТКС>>>>Ну будет подвисание, и что? Большая что ли проблема вынести GUI в одну нить, COM — в другой?

_>>>Конечно, так и делаем.
_>>>В общем случае задача сводиться к следующему: Есть некий outproc COM сервер. Я хочу достоверно знать что он не висит( или не в длительном busy) не обращаясь к его методам, поскольку любое обращение к этим самым методам приведет к завесу( или значительной задержке) моего потока.

ТКС>>Не-не-не, все гораздо хуже. Выше сформулированная задача хотя бы теоретически может иметь решение. А на самом деле ты хочешь достоверно знать, не повиснет ли COM сервер при следующем обращении, а не в момент проверки. Что в общем случае, естественно, не решается в принципе.

_>Хорошо, как хотя-бы проверку сделать? Я не хочу делать вообще никаких обращений пока сервер висит, и только если сервер ready вызывать его методы. Есть конечно теоретическая вероятность того что сервер успеет повиснуть между проверкой на busy и последуюшим обращением, но с этим я в принципе готов смириться и попробовать прервать зависший вызов.

В общем случае — никак, естественно, не сделать. Очень часто вообще нет такого понятия как ready. При одних параметрах вызова сервер будет тупить 100 мс, при других — 100 с, при третьих — вообще упадет. Поэтому никто ни каких проверок на готовность при разработке COM видимо и не предусматривал. Если все равно сильно хочется — ну можно сделать свою проксю, которая в отдельной нити будет ставить запрос в очередь, а на время выполнения выставлять читаемый клиентом флаг и на любые вызовы возвращать какой-нибудь RPC_E_RETRY. Только, IMHO, это изначально кривой путь.
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Re[12]: как работать с проблемной dll?
От: alexey_ma Израиль  
Дата: 27.01.10 17:38
Оценка:
Здравствуйте, Тот кто сидит в пруду, Вы писали:

ТКС>Это неправильная постановка задачи, IMHO. Правильная — писать программу так, чтобы зависший поток ничему не мешал. Вот пишу я допустим программу сетевого обмена — она постоянно ждет либо ответа/запроса из сети, либо ввода пользователя либо какого-нибудь еще события. Если сеть сразу не отвечает — ничего страшного, это штатная ситуация. Придет ответ — отреагируем.

Не подходит. Я писал что когда есть возможность получать эвенты от сервера это совсем другая работа, там как раз все нормально. Тот же браузер например, получил эвент document ready/complete и вперед. Но такое не всегда возможно.

_>>Хорошо, как хотя-бы проверку сделать? Я не хочу делать вообще никаких обращений пока сервер висит, и только если сервер ready вызывать его методы. Есть конечно теоретическая вероятность того что сервер успеет повиснуть между проверкой на busy и последуюшим обращением, но с этим я в принципе готов смириться и попробовать прервать зависший вызов.


ТКС>В общем случае — никак, естественно, не сделать. Очень часто вообще нет такого понятия как ready. При одних параметрах вызова сервер будет тупить 100 мс, при других — 100 с, при третьих — вообще упадет. Поэтому никто ни каких проверок на готовность при разработке COM видимо и не предусматривал. Если все равно сильно хочется — ну можно сделать свою проксю, которая в отдельной нити будет ставить запрос в очередь, а на время выполнения выставлять читаемый клиентом флаг и на любые вызовы возвращать какой-нибудь RPC_E_RETRY. Только, IMHO, это изначально кривой путь.

Про прокси можно подумать. А пока мой метод с SendMessageTimeout достаточно надежно работает, только не у всех серверов есть окна . Есть еще асинхронные сервера, где в принципе можно сделать саncel запросу, но мне пока таковые не попадались.
Re[13]: как работать с проблемной dll?
От: Тот кто сидит в пруду Россия  
Дата: 27.01.10 18:22
Оценка:
Здравствуйте, alexey_ma, Вы писали:

ТКС>>Это неправильная постановка задачи, IMHO. Правильная — писать программу так, чтобы зависший поток ничему не мешал. Вот пишу я допустим программу сетевого обмена — она постоянно ждет либо ответа/запроса из сети, либо ввода пользователя либо какого-нибудь еще события. Если сеть сразу не отвечает — ничего страшного, это штатная ситуация. Придет ответ — отреагируем.

_>Не подходит. Я писал что когда есть возможность получать эвенты от сервера это совсем другая работа, там как раз все нормально. Тот же браузер например, получил эвент document ready/complete и вперед. Но такое не всегда возможно.

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

_>>>Хорошо, как хотя-бы проверку сделать? Я не хочу делать вообще никаких обращений пока сервер висит, и только если сервер ready вызывать его методы. Есть конечно теоретическая вероятность того что сервер успеет повиснуть между проверкой на busy и последуюшим обращением, но с этим я в принципе готов смириться и попробовать прервать зависший вызов.


ТКС>>В общем случае — никак, естественно, не сделать. Очень часто вообще нет такого понятия как ready. При одних параметрах вызова сервер будет тупить 100 мс, при других — 100 с, при третьих — вообще упадет. Поэтому никто ни каких проверок на готовность при разработке COM видимо и не предусматривал. Если все равно сильно хочется — ну можно сделать свою проксю, которая в отдельной нити будет ставить запрос в очередь, а на время выполнения выставлять читаемый клиентом флаг и на любые вызовы возвращать какой-нибудь RPC_E_RETRY. Только, IMHO, это изначально кривой путь.

_>Про прокси можно подумать. А пока мой метод с SendMessageTimeout достаточно надежно работает, только не у всех серверов есть окна .

Вообще COM, когда я последний раз им интересовался, был реализован с использованием скрытых окон — видимо, MS было лень писать еще одну очередь сообщений. Можно попробовать с ним работать — если оно в винде еще наличествует.
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Re[14]: как работать с проблемной dll?
От: alexey_ma Израиль  
Дата: 28.01.10 07:50
Оценка:
Здравствуйте, Тот кто сидит в пруду, Вы писали:

_>>Не подходит. Я писал что когда есть возможность получать эвенты от сервера это совсем другая работа, там как раз все нормально. Тот же браузер например, получил эвент document ready/complete и вперед. Но такое не всегда возможно.


ТКС>Зачем события? С сетью все замечательно делается даже на обычных блокирующих операциях, следовательно, и в других случаях можно вполне жить с блокировками.

Эвенты CОМ-а по сути те-же блокирующие операции, реализация не так уж важна, важна сама возможность получать события/уведомления о изменении состояния сервера и возможность самому инициировать cобытия на сервере. В этом случае как-раз то можно все более мене нормально сделать.

ТКС>>>В общем случае — никак, естественно, не сделать. Очень часто вообще нет такого понятия как ready. При одних параметрах вызова сервер будет тупить 100 мс, при других — 100 с, при третьих — вообще упадет. Поэтому никто ни каких проверок на готовность при разработке COM видимо и не предусматривал. Если все равно сильно хочется — ну можно сделать свою проксю, которая в отдельной нити будет ставить запрос в очередь, а на время выполнения выставлять читаемый клиентом флаг и на любые вызовы возвращать какой-нибудь RPC_E_RETRY. Только, IMHO, это изначально кривой путь.

_>>Про прокси можно подумать. А пока мой метод с SendMessageTimeout достаточно надежно работает, только не у всех серверов есть окна .

ТКС>Вообще COM, когда я последний раз им интересовался, был реализован с использованием скрытых окон — видимо, MS было лень писать еще одну очередь сообщений. Можно попробовать с ним работать — если оно в винде еще наличествует.

Ага, COM STA использует скрытые окна, я очень давно пробовал пробовал их опрашивать, просто оказалось что с гуевым окном сервера проще. Мне в основном интересны сервера имеющие гуй, в этом случае перед обращением к СОМ-у еще иногда можно проверить процесс на InputIdle.