Обнаружение маршалинга кросс-потоков объектами 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