Я работаю над COM API, написанным на C ++ с ATL, который клиенты будут использовать в C # через средства взаимодействия COM. В настоящее время все объекты COM написаны только для поддержки однопоточной модели квартиры.
Некоторые функции этого API вызывают создание отдельного рабочего потока, который прослушивает события с сервера. В ответ на события с сервера этот рабочий поток создает несколько довольно простых объектов COM, а затем передает эти объекты в событие COM. В API есть другие функции, которые заставляют API прекращать прослушивание событий с сервера, а затем отключают рабочие потоки.
Насколько я понимаю, правила STA таковы, что код для COM-объекта STA будет выполняться только в том потоке, в котором он создан. К сожалению, это, кажется, вызывает отключение контекстных предупреждений, поскольку COM-взаимодействие .NET кэширует ссылки на все COM-объекты, созданные в этом потоке, и поток закрывается, прежде чем эти ссылки освобождаются.
Я вижу несколько возможных решений этой проблемы:
- Я мог бы изменить наши COM-объекты для поддержки потоковой модели MTA, поэтому уничтожение создаваемого им потока больше не является проблемой. Однако это может быть довольно трудоемкой задачей и может открыть для меня другие проблемы, связанные с многопоточностью.
- Я мог бы добавить подсчет ссылок, чтобы рабочий поток оставался активным до тех пор, пока все его COM-объекты не будут освобождены. Похоже, что это может быть ошибочным подходом.
- Я мог бы добавить целый новый поток, предназначенный для вечной работы (или, по крайней мере, до конца приложения), который занимается созданием объектов COM и созданием событий. Наличие одного потока для этой цели, вероятно, создаст некоторое узкое место в производительности, которое мне не очень нравится.
Кажется, что все вышеперечисленные подходы имеют свои недостатки, поэтому мне было интересно, есть ли у кого-нибудь еще опыт решения подобных проблем? Или есть ли какие-либо преимущества или недостатки, о которых я не упомянул для вышеупомянутых подходов?