Обнаружение маршалинга кросс-потоков объектами COM RCW в С#

Я работаю в больших многопоточных приложениях С#, обрабатывающих пучки COM-взаимодействия. У других разработчиков и у меня есть широкая возможность случайно вызвать однопоточную квартиру (STA) COM-объекты из потоков MTA, а также из потоков STA, которые они weren ' т. Производительность вялая, а перекрестная сортировка - главный подозреваемый.

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

Ближайший я пришел, это утверждение, защищающее подозрительный код:

Debug.Assert(Thread.CurrentThread.GetApartmentState() == ApartmentState.STA);
suspiciousComInterface.SomeMethod();

Пока это будет предупреждать нас, если наши потоки BackgroundWorker вызывают объекты STA, я особенно обеспокоен тем, что потоки STA используют объекты COM Runtime Callable Wrapper (RCW), созданные в другом потоке STA.

Один онлайн-источник предположил, что это невозможно (http://www.pcreview.co.uk/forums/detecting-cross-apartment-com-calls-t2450589.html), что CLR скрывает слишком много объектов COM-прокси до сделать их доступными на высоком уровне.

Не могу поверить, что это единственный ответ. Спасибо!

Ответ 1

Вы должны выполнить это, проверив, можете ли вы перейти на интерфейс IMarshal, который должен быть агрегирован в прокси-сервер, если вызов является межсетевым вызовом. Во-первых, вам нужно будет объявить IMarshal где-то в вашем проекте:

  [System.Runtime.InteropServices.InterfaceTypeAttribute(1)]
  [System.Runtime.InteropServices.Guid("00000003-0000-0000-C000-000000000046")]
  public interface IMarshal
  {
     // no methods needed, just querying for the interface
  }

Затем вы можете проверить интерфейс таким образом.

  if (suspiciousComInterface is IMarshal)
     // cross-apartment call
  else
     // direct call