Неспособный бросить COM-объект исключения типа

Говорит итератору, что он достиг конца.

Как пример:

public interface INode
{
    IEnumerable<Node> GetChildren();
}

public class NodeWithTenChildren : INode
{
    private Node[] m_children = new Node[10];

    public IEnumerable<Node> GetChildren()
    {
        for( int n = 0; n < 10; ++n )
        {
            yield return m_children[ n ];
        }
    }
}

public class NodeWithNoChildren : INode
{
    public IEnumerable<Node> GetChildren()
    {
        yield break;
    }
}
20
задан Kyle 5 August 2009 в 14:04
поделиться

2 ответа

Это неприятное, неприятное исключение возникает из-за концепции, известной как маршаллинг COM. Суть проблемы заключается в том, что для использования COM-объектов из любого потока поток должен иметь доступ к информации о типе, описывающей COM-объект.

В описанном вами сценарии причина сбоя во втором потоке заключается в том, что второй поток не имеет информации о типе для интерфейса.

Вы можете попробовать добавить в свой код следующее:

[ComImport]
[Guid("23EB4AF8-BE9C-4b49-B3A4-24F4FF657B27")]
public interface IMyInterface
{
    void CallMethod();
}

В основном объявление выше указывает загрузчику COM платформы .NET Framework загрузить информацию о типах из реестра, используя традиционные методы, найти соответствующую библиотеку типов и перейти оттуда.

Вы также должны ограничить создание COM-объекта одним потоком (чтобы предотвратить маршалинг потоков), чтобы помочь решить эту проблему.

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

PS: Эта проблема решена в .NET 4.0 с помощью метода, называемого «эквивалентность типов»

21
ответ дан 30 November 2019 в 00:59
поделиться

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

private IMyInterface myInterface;
private static readonly object _myObjectLock = new object();

public void Test(IMyInterface iInterface)
{
     myInterface = iInterface;
     new Thread ( new ThreadStart ( CallInterfaceMethod) ).Start ( );
}

public void CallInterfaceMethod ( )
{
     lock(_myObjectLock)
     {
        myInterface.CallMethod ( );
     }
}

Насколько я понимаю, указанная вами ошибка может иногда возникать, когда к ресурсу невозможно получить доступ, что, скорее всего, произойдет при такой операции с несколькими потоками. Не цитируйте меня по этому поводу, я не эксперт в области COM.

Честно говоря, я не думаю, что подошел бы к вызову этого метода таким образом, слишком много рисков при этом. Рассматривали ли вы использование ParameterizedThreadStart и передачу объекта таким образом? Вам все равно потребуется надежно заблокировать свои объекты для межпоточных операций, но это будет безопаснее.

Кроме того, убедитесь, что ваш класс "myInterface" по-прежнему может вызывать "

-1
ответ дан 30 November 2019 в 00:59
поделиться
Другие вопросы по тегам:

Похожие вопросы: