Re: Асинхронный вызов IAdviseSink в Win2000
От: Sergey Россия  
Дата: 18.04.02 06:01
Оценка: 2 (1)
Здравствуйте greatvict, Вы писали:

G>Я использую интерфейс IAdviseSink для приема данных от OPC-серверов стандарта 1.0 (сервер с некоторым периодом отправляет клиенту через IAdviseSink::OnDataChange некоторые данные). Мой sink находится в многопоточном апартаменте.


G>В операционной системе Windows 2000 возникла следующая проблема — если я в клиенте не успеваю обрабатывать вызовы IAdviseSink::OnDataChange, то происходит взрывное увеличение количества одновременных входящих вызовов, и, соответственно, такое же увеличение количества потоков, в которых эти вызовы обрабатываются. Стек при вызове выглядит следующим образом —


G>COPCGroupDef::OnDataChange(COPCGroupDef * const 0x08022b48, tagFORMATETC * 0x07d20758, tagSTGMEDIUM * 0x07d2f3c8)

G>OLE32! AsyncIAdviseSink_Begin_OnDataChange_Stub@12 + 18 bytes
G>OLE32! AsyncIAdviseSink_Begin_RemoteOnDataChange_Thunk@4 + 21 bytes
G>RPCRT4! NdrStubCall2@16 + 27498 bytes
G>........................


G>Это очень похоже на асинхронный вызов синхронного интерфейса Win2000, но серверы были выпущены до выхода Windows 2000 и, понятное дело, никаких специфичных для Win2000 средств использвать не могут. Получается, что Win2000 сама решила, что, поскольку OnDataChange не имеет out-параметров, то ее вполне можно вызывать асинхронно с точки зрения сервера.


Насколько я знаю, outgoing вызовы (события) всегда были асинхронными. В частности, в описании интерфейса IAdviseSink про это говориться: Calls to IAdviseSink methods are asynchronous, so the call is sent and then the next instruction is executed without waiting for the call's return

G>Кто нибудь сталкивался с подобной проблемой?


Сталкивался с похожей — в Win2000 сильно поменялись "потроха" COM. Все в пределах спецификации, но ошибки в программе, которые не проявлялись на NT, все разом вылезли наружу.
На твоем месте я бы завел очередь, куда быстро укладывал бы данные, приходящие в OnDataChange, и рабочий поток, который медленно (вернее, так быстро, как только возможно ) разбирал бы очередь. Впрочем, если у тебя клиент за сервером не успевает в среднем, а не только при пиковой загрузке, все равно не поможет.

G>P.S. Проблема обнаружилась, после того, как программа упала, когда количество потоков перевалило за тысячу.


Памяти под стеки потоков не хватило?
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Асинхронный вызов IAdviseSink в Win2000
От: greatvict www.insat.ru
Дата: 18.04.02 05:36
Оценка:
Я использую интерфейс IAdviseSink для приема данных от OPC-серверов стандарта 1.0 (сервер с некоторым периодом отправляет клиенту через IAdviseSink::OnDataChange некоторые данные). Мой sink находится в многопоточном апартаменте.

В операционной системе Windows 2000 возникла следующая проблема — если я в клиенте не успеваю обрабатывать вызовы IAdviseSink::OnDataChange, то происходит взрывное увеличение количества одновременных входящих вызовов, и, соответственно, такое же увеличение количества потоков, в которых эти вызовы обрабатываются. Стек при вызове выглядит следующим образом —

COPCGroupDef::OnDataChange(COPCGroupDef * const 0x08022b48, tagFORMATETC * 0x07d20758, tagSTGMEDIUM * 0x07d2f3c8)
OLE32! AsyncIAdviseSink_Begin_OnDataChange_Stub@12 + 18 bytes
OLE32! AsyncIAdviseSink_Begin_RemoteOnDataChange_Thunk@4 + 21 bytes
RPCRT4! NdrStubCall2@16 + 27498 bytes
........................


Это очень похоже на асинхронный вызов синхронного интерфейса Win2000, но серверы были выпущены до выхода Windows 2000 и, понятное дело, никаких специфичных для Win2000 средств использвать не могут. Получается, что Win2000 сама решила, что, поскольку OnDataChange не имеет out-параметров, то ее вполне можно вызывать асинхронно с точки зрения сервера.

Кто нибудь сталкивался с подобной проблемой?

P.S. Проблема обнаружилась, после того, как программа упала, когда количество потоков перевалило за тысячу.
Re[2]: Асинхронный вызов IAdviseSink в Win2000
От: Момотов Виктор Сергеевич www.insat.ru
Дата: 19.04.02 04:30
Оценка:
Здравствуйте Sergey, Вы писали:

G>>Я использую интерфейс IAdviseSink для приема данных от OPC-серверов стандарта 1.0 (сервер с некоторым периодом отправляет клиенту через IAdviseSink::OnDataChange некоторые данные). Мой sink находится в многопоточном апартаменте.


S>Насколько я знаю, outgoing вызовы (события) всегда были асинхронными. В частности, в описании интерфейса IAdviseSink про это говориться: Calls to IAdviseSink methods are asynchronous, so the call is sent and then the next instruction is executed without waiting for the call's return


Да, я как то пропустил это (надо почаще в MSDN залезать)... Хорошо, что новый стандарт OPC 2.0 использует ConnectionPoint-ы, вызовы через которые синхронные.

S>На твоем месте я бы завел очередь, куда быстро укладывал бы данные, приходящие в OnDataChange, и рабочий поток, который медленно (вернее, так быстро, как только возможно ) разбирал бы очередь. Впрочем, если у тебя клиент за сервером не успевает в среднем, а не только при пиковой загрузке, все равно не поможет.


Да, отложенная обработка в моем случае проблему целиком не решит, так что пришлось пока отклонять новые входящие вызовы при превышении некоторого порога одновременно обрабатываемых. А по-хорошему надо регулировать входящий поток (типа период опроса увеличивать).

G>>P.S. Проблема обнаружилась, после того, как программа упала, когда количество потоков перевалило за тысячу.


S>Памяти под стеки потоков не хватило?


Программа не совсем падает, просто подвисает конкретно. А так вообще до 2000 потоков иногда доходило...
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.