Нужно ли вызывать CoInitialize перед взаимодействием с COM в .NET?

Я знаю, что требование COM, чтобы каждый поток вызывал CoInitialize перед взаимодействием с системой COM.

.NET предоставляет некоторые элементы, которые внутренне работают с потоками, например:

  • ThreadPool threads
  • asychronous delegates (которые используют потоки пула потоков)
  • BackgroundWorker class (который использует asychronous delegates (которые используют потоки пула потоков))
  • the garbage collector
  • and more! (т.е., например)

Если я собираюсь взаимодействовать с COM-объектом из потока, нужно ли мне сначала вызвать CoInitialize ?

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


Бонусное чтение

Управляемые и неуправляемые потоки

Для обеспечения совместимости среда выполнения общего языка создает и инициализирует квартиру при вызове COM-объекта. Управляемый поток может создать и войти в однопоточный апартамент (STA), который содержит только один поток, или многопоточный апартамент (MTA), который содержит один или более потоков. Когда апартамент COM и созданный потоком апартамент совместимы, COM позволяет вызывающему потоку выполнять вызовы непосредственно к объекту COM. Если апартаменты несовместимы, COM создает совместимый апартамент и передает все вызовы через прокси в новый квартире.

Время выполнения вызывает CoInitializeEx для инициализации апартамента COM как либо MTA, либо STA.

Обновление второе:

Похоже, не стоит использовать COM из любого вида потоков, которые может предоставить .NET:

Управляемый пул потоков

Есть несколько сценариев, в которых целесообразно создавать и управлять своими собственными потоками вместо использования потоков пула потоков:

  • Вам нужен поток переднего плана.

  • Вам требуется, чтобы поток имел определенный приоритет.

  • У вас есть задачи, которые заставляют поток блокироваться в течение длительных периодов времени. времени. Пул потоков имеет максимальное количество потоков, поэтому большое количество заблокированных потоков в пуле потоков может помешать задачам запустить.

  • Вам нужно поместить потоки в однопоточную квартиру. Все ThreadPool потоки находятся в многопоточном апартаменте.

  • Вам нужно иметь стабильную идентификацию, связанную с потоком, или посвятить поток задаче.

Обновление три:

Похоже, вы можете установить модель потоковой обработки неизменяемых потоков:

Managed and Unmanaged Threading in Microsoft Windows

Управляемый поток может быть помечен, чтобы указать, что он будет находиться в однопоточном или многопоточном апартаменте. Методы GetApartmentState, SetApartmentState и TrySetApartmentState класса Thread возвращают и присваивают состояние апартаментов потока. Если состояние не было установлено, GetApartmentState возвращает ApartmentState.Unknown.

Свойство может быть установлено только тогда, когда поток находится в состоянии ThreadState.Unstarted; оно может быть установлено только один раз для потока.

Если состояние квартиры не установлено до запуска потока, поток инициализируется как многопоточная квартира (MTA).

Много противоречивой информации.

Поэтому мы будем использовать то, что сказал парень на Stackoverflow, как истинный ответ.

12
задан Ian Boyd 17 January 2012 в 21:53
поделиться