При создании COM-сервера вне процесса в C #, как описано в примере кода Microsoft All-In-One: CSExeCOMServer , кажется трудным управлять моделью потоков объектов, которые создаются в сервер (клиентом).
Создаемый объект должен находиться в STA, поскольку он использует объекты WPF, а его фабрика регистрируется, как показано в строке 95 ExeCOMServer.cs , и вставляется ниже ...
private void PreMessageLoop()
{
//
// Register the COM class factories.
//
Guid clsidSimpleObj = new Guid(SimpleObject.ClassId);
// Register the SimpleObject class object
int hResult = COMNative.CoRegisterClassObject(
ref clsidSimpleObj, // CLSID to be registered
new SimpleObjectClassFactory(), // Class factory
CLSCTX.LOCAL_SERVER, // Context to run
REGCLS.MULTIPLEUSE | REGCLS.SUSPENDED,
out _cookieSimpleObj);
if (hResult != 0)
{
throw new ApplicationException(
"CoRegisterClassObject failed w/err 0x" + hResult.ToString("X"));
}
Однако функция CreateInstance всегда вызывается в новом потоке, который находится в MTA. Кажется, не имеет значения, что основной поток локального сервера помечен (и проверен) как поток STA.
Все найденные материалы свидетельствуют о том, что квартира созданных объектов должна соответствовать квартире нити, в которой была зарегистрирована фабрика. Фактически, это, кажется, имеет место при использовании COM-сервера ATL (смешанного с Managed C ++ для создания объектов), но этот метод, по-видимому, внедряет новый поток в рабочий поток, который инициализирует параметры, особенно модель потоков COM. , не представляется изменяемым.
Кто-нибудь решил эту проблему, не прибегая к COM-серверу, написанному в основном неуправляемым кодом.