Здравствуйте, silart, Вы писали:
S>Внесем ясность.
Удачная мысль
S>Понятно, что конструктор вызывается другим (по отношению к отправляющему события) потоком.
S>Таким образом, pITypeInfo получается в конструкторе одним потоком, а используется в потоковой функции другим потоком. Нужно ли здесь использовать маршалинг? Ведь по идее должно было все обрушиться и при одном компоненте, а все работает.
Ну а с чего бы ему обрушаться

Когда Вы просто передаёте куда-то интерфейс, без маршалинга, Вы фактически передаёте адрес таблицы в памяти, содержащей адреса методов, реаслизующих этот интерфейс. При этом вызов метода интерфейса — это просто самый обыкновенный вызов функции по адресу. Вы же не пишите в реализации каждого метода проверку валидности текущего апартамента и не генерите по этому поводу исключений, откуда же возьмётся обрушение? И никто этого не делает, потому что это не задача объекта. Это задача для прокси, и у него есть для этого необходимые средства. Когда Вы попытаетесь вызвать метод прокси из чужого для него апартамента, тот обратится за RPC буфером к менеджеру канала, а тот в ответ вернёт WRONG_THREAD. В случае же прямого вызова такой проверки сделать просто некому.
S>Мизантроп, если речь идет о компоненте без событий, то с STA все понятно. А как задать STA, если речь идет о генерации событий? Как задать STA именно для событийного потока явно?
Апартаментная модель для потока всегда задаётся одинаково — вызовом CoInitialize(Ex).
Потоковая модель клиента — это одно, а поддерживаемая сервером — другое, и они друг от друга не зависят. Каждый из них выбирает ту модель, которую считает для себя наиболее подходящей, и маршалинг как раз и служит для согласования этих моделей.
От наличия событий тут тоже мало что зависит, только что общая логика усложняется. И любой событийный интерфейс, и любой "инфраструктурный" интерфейс поддержки событий — это самые обыкновенные интерфейсы, и к ним применимы все те-же правила, что и к любым другим. А правило простое —
любой интерфейс должен пердаваться в другой апартамент только через маршалинг.
Например, Вы похоже pIConnectionPoint передаёте без маршалинга, что уже является ошибкой.
Но вообще мне, честно говоря, не очень нравится Ваша схема. Я бы сразу при подписке маршалировал событийный интерфейс в GIT, а в потоке один раз их демаршалировал. Разумеется, это потребует реализации собственного механизма подписки — IConnectionPointContainer для этого не слишком удачный выбор, но оно того стоит, по-моему. Если конечно вообще оправдана генерация событий в отдельном потоке. Может лучше чтобы доп. поток извещал главный о завершении обработки, а тот уже генерировал бы события?
S>А могут быть проблемы от "кривости" клиента? Клиент написан на Borland C++ Builder.
Я билдера не знаю, но сильно сомневаюсь.