无法转换异常类型的COM对象

问题描述 投票:20回答:4

我有以下代码:

public void Test(IMyInterface iInterface)
{
  iInterface.CallMethod ( );
}

工作正常。不过,如果我更改代码能够拧:

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

public void CallInterfaceMethod ( )
{
  myInterface.CallMethod ( )
}

当我使用线程我收到异常:

无法转换类型的COM对象“系统.__ ComObject”到接口类型“IMyInterface的”。此操作失败的原因是对IID由于后续的错误而失败的接口“{GUID}”的COM组件调用QueryInterface:不支持此接口

但接口应该支持就好了?任何人有什么是怎么回事有什么想法?

c# com interface
4个回答
21
投票

这讨厌,讨厌的例外的产生是因为被称为COM编组的一个概念。问题的实质在于一个事实,即以消耗从任何线程COM对象,线程必须能够访问描述COM对象的类型信息。

在您的方案中所述,它的第二个线程上失败的原因是因为第二个线程不具有的接口类型信息。

你可以尝试加入以下代码:

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

以上基本上声明指示.NET框架COM加载器使用传统技术从注册表加载类型信息,并找到相关的类型库,并从那里走。

你也应该限制COM对象到单个线程的创建(防止螺纹编组),以帮助解决这个问题。

总之,这个错误身边类型的信息和线程编组旋转。确保每个需要访问COM对象的线程有相关的信息解组原线的对象。

PS:这个问题就解决了在.NET 4.0中使用一种称为“类等”技术


4
投票

我有一个建议,它帮助了我!

发现在主线程(Program.cs中)的线[STAThread]并将其改为[MTAThread]。


0
投票

我一直在开发一种使用通过COM接口,7-ZIP C#应用程序。我就遇到了这个有趣的事情,我能在一个实例从一个工作线程提取档案,而不是另一个,得到这同样的异常。

我发现,只要你初始化它不使用异常的线程问题的COM对象被抛出。我的解决办法是处置其利用COM接口和在线程之间传递时它们重新初始化它们的对象。


-1
投票

那么,对于一个,你是一个跨线程调用一个对象而将其锁定,这将自动导致一些问题。你的代码应该看起来更像是:

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的”类仍然可以拨打“CallMethod()”方法。接口没有实现,你可能遇到了问题,当你设置“MyInterface的= iInterface”。

© www.soinside.com 2019 - 2024. All rights reserved.