Предотвращение отключения контекстного предупреждения при закрытии потока, в котором созданы объекты STA COM - PullRequest
0 голосов
/ 09 ноября 2011

Я работаю над COM API, написанным на C ++ с ATL, который клиенты будут использовать в C # через средства взаимодействия COM. В настоящее время все объекты COM написаны только для поддержки однопоточной модели квартиры.

Некоторые функции этого API вызывают создание отдельного рабочего потока, который прослушивает события с сервера. В ответ на события с сервера этот рабочий поток создает несколько довольно простых объектов COM, а затем передает эти объекты в событие COM. В API есть другие функции, которые заставляют API прекращать прослушивание событий с сервера, а затем отключают рабочие потоки.

Насколько я понимаю, правила STA таковы, что код для COM-объекта STA будет выполняться только в том потоке, в котором он создан. К сожалению, это, кажется, вызывает отключение контекстных предупреждений, поскольку COM-взаимодействие .NET кэширует ссылки на все COM-объекты, созданные в этом потоке, и поток закрывается, прежде чем эти ссылки освобождаются.

Я вижу несколько возможных решений этой проблемы:

  1. Я мог бы изменить наши COM-объекты для поддержки потоковой модели MTA, поэтому уничтожение создаваемого им потока больше не является проблемой. Однако это может быть довольно трудоемкой задачей и может открыть для меня другие проблемы, связанные с многопоточностью.
  2. Я мог бы добавить подсчет ссылок, чтобы рабочий поток оставался активным до тех пор, пока все его COM-объекты не будут освобождены. Похоже, что это может быть ошибочным подходом.
  3. Я мог бы добавить целый новый поток, предназначенный для вечной работы (или, по крайней мере, до конца приложения), который занимается созданием объектов COM и созданием событий. Наличие одного потока для этой цели, вероятно, создаст некоторое узкое место в производительности, которое мне не очень нравится.

Кажется, что все вышеперечисленные подходы имеют свои недостатки, поэтому мне было интересно, есть ли у кого-нибудь еще опыт решения подобных проблем? Или есть ли какие-либо преимущества или недостатки, о которых я не упомянул для вышеупомянутых подходов?

1 Ответ

0 голосов
/ 11 ноября 2011

В итоге я выбрал вариант 1 в исходном вопросе и переключил каждый из COM-объектов для работы в модели потоков MTA. Все COM-объекты были просто оболочками, доступными только для чтения, для некоторых данных, поэтому они уже были в основном ориентированы на многопотоковое исполнение, и переключение на MTA было всего лишь случаем обновления нескольких файлов .rgs и некоторых вызовов CoInitializeEx.

Возможно, не идеальное решение для всех, но, надеюсь, это поможет всем, кто столкнется с этой проблемой в будущем.

...