Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: COM/DCOM/ActiveX/ATL/CORBA > Таймаут COM-вызова


Автор: iljy 23.6.2013, 17:48
Всем доброго времени суток.

Подскажите плз, есть ли адекватный способ установить таймаут на вызов COM-метода на стороне клиента?

Опишу задачу поподробнее:
имеется приложение-сервис, которое в процессе работы получает данные через COM-вызовы у другого сервиса (у OPC-сервера, если это поможет). Сервисы физически на разных компах, и соединение между ними ненадежно, связь периодически рвется. Проблема в том, что вызов при этом замирает на приличное время (секунд 40-45), что очень неприятно, при этом в нормальных условиях ответ получается быстро, так что если его нет 2-3 секунды - уже понятно, что беда.

Единственный более-менее вменяемый вариант, который я нагуглил - использовать IMessageFilter::MessagePending и прерывать выполнение при превышении времени, но, как я сказал, приложение-сервис, пользовательских сообщений нет, так что придется городить какой-то таймер и рассылать сообщения самому себе. Можно, но как-то громоздко и коряво.

PS Предупреждая лишние уходы в сторону: не надо рассказывать про многопоточные приложения и асинхронное чтение, сервис уже и так многопоточный, а асинхронными можно сделать не все вызовы, да и в данном конкретном случае обратные RPC запрещены политиками домена. Я также знаю, что можно вешать на данные таймстампы и проверять их давность и т.п, и принудительно рубить поток, выполняющий вызов, эти решения очевидны, равно как и очевидны их недостатки. Хотя, возможно, есть какие-то другие варианты применения таких подходов, которые я не учел smile

Спасибо!

Автор: xvr 24.6.2013, 14:06
http://msdn.microsoft.com/en-us/library/windows/desktop/ms692623%28v=vs.85%29.aspx не подойдут?

Автор: iljy 25.6.2013, 00:08
Цитата(xvr @  24.6.2013,  14:06 Найти цитируемый пост)
Асинхронные COM вызовы не подойдут?


Не-а. Проблема же не в том, что вызов долго выполняется, а в том, что отвалилось соединение и до сервера запрос просто не доходит, но возврат управления клиенту происходит по истечении внутреннего таймаута, а он очень большой.

Автор: xvr 25.6.2013, 00:48
Асинхронный вызов позволяет сначала позвать метод, а потом ждать его окончания с заданным таймаутом. По моему это именно то, что вам было нужно?

Добавлено через 3 минуты и 1 секунду
Осталось только убедится, что сервер поддерживает асинхронные вызовы, а это далеко не всегда так  smile

Добавлено через 11 минут и 7 секунд
Вот, еще нашел http://msdn.microsoft.com/en-us/library/windows/desktop/ms691210%28v=vs.85%29.aspx. Очень похоже на то, что вы хотели.

Автор: iljy 25.6.2013, 02:13
Цитата(xvr @  25.6.2013,  00:48 Найти цитируемый пост)
Асинхронный вызов позволяет сначала позвать метод, а потом ждать его окончания с заданным таймаутом. По моему это именно то, что вам было нужно?
Добавлено через 3 минуты и 1 секунду
Осталось только убедится, что сервер поддерживает асинхронные вызовы, а это далеко не всегда так  


Из описания метода я не понял, где именно реализуются Begin_... Finis_... и интерфейс ISynchronize, если на стороне клиента - то можно попробовать, а если на стороне сервера - так они сами  и встанут в таймаут, если соединение пропало smile

Цитата(xvr @  25.6.2013,  00:48 Найти цитируемый пост)
Вот, еще нашел нечто. Очень похоже на то, что вы хотели.


О, а вот это похоже! Спасибо, буду разбираться smile

Автор: xvr 25.6.2013, 11:49
Цитата(iljy @  25.6.2013,  02:13 Найти цитируемый пост)
Из описания метода я не понял, где именно реализуются Begin_... Finis_... и интерфейс ISynchronize,

На стороне сервера должен быть реализован ICallFactory. Остальное реализует сам DCOM

Цитата(iljy @  25.6.2013,  02:13 Найти цитируемый пост)
а если на стороне сервера - так они сами  и встанут в таймаут, если соединение пропало

Нет, Begin_ возвращается немедленно, не дожидаясь ответа от сервера. Этим заведуют proxy из DCOM'а

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)