Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/290.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 无法强制转换类型为exception的COM对象_C#_Com_Interface - Fatal编程技术网

C# 无法强制转换类型为exception的COM对象

C# 无法强制转换类型为exception的COM对象,c#,com,interface,C#,Com,Interface,我有以下代码: public void Test(IMyInterface iInterface) { iInterface.CallMethod ( ); } 这很好用。但是,如果我将代码更改为线程化: private IMyInterface myInterface; public void Test(IMyInterface iInterface) { myInterface = iInterface; new Thread ( new ThreadStart ( CallI

我有以下代码:

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 ( )
}
当我使用线程时,我收到异常:

无法将“System.\u ComObject”类型的COM对象强制转换为接口类型“IMyInterface”。 此操作失败,因为对IID为“{GUID}”的接口的COM组件的QueryInterface调用失败,原因是出现以下错误:不支持此类接口


但是界面应该得到很好的支持?有人对这里发生的事情有什么想法吗?

首先,您正在对一个对象进行跨线程调用,但没有锁定它,这会自动导致一些问题。您的代码应该更像:

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专家

老实说,我不认为我会用这种方式来称呼这个方法,因为这样做有太多的风险。你有没有考虑过使用一种方法,并通过这种方式传递对象?您仍然需要为跨线程操作安全地锁定对象,但这样会更安全


此外,请检查以确保“myInterface”类仍然可以调用“CallMethod()”方法。接口没有实现,当您设置“myInterface=iInterface”时,可能会遇到问题。

这种令人讨厌的异常是由于一种称为COM编组的概念而产生的。问题的本质在于,为了从任何线程使用COM对象,线程必须能够访问描述COM对象的类型信息

在您描述的场景中,它在第二个线程上失败的原因是第二个线程没有接口的类型信息

您可以尝试将以下内容添加到代码中:

[ComImport]
[Guid("23EB4AF8-BE9C-4b49-B3A4-24F4FF657B27")]
public interface IMyInterface
{
    void CallMethod();
}
基本上,上面的声明指示.NET framework COM加载器使用传统技术从注册表加载类型信息,并找到关联的类型库,然后从那里开始

还应将COM对象的创建限制为单个线程(以防止线程编组),以帮助解决此问题

总之,此错误与类型信息和线程编组有关。确保要访问COM对象的每个线程都具有相关信息,以便从源线程解组该对象


PS:这个问题在.NET4.0中使用了一种称为“类型等价”的技术解决了。

我得到了一个建议,它帮助了我

在主线程(Program.cs)中找到[STAThread]行并将其更改为[MTAThread]。

我一直在开发一个通过COM接口使用7-zip的C#应用程序。我遇到了一件有趣的事情,在一个实例中,我能够从一个工作线程中提取归档,但在另一个实例中,我却没有,得到了同样的异常


我发现,只要在使用它的线程中初始化有问题的COM对象,就不会引发异常。我的解决方案是处置使用COM接口的对象,并在线程之间传递它们时重新初始化它们。

答案比您更清楚,但使用ParameterizedThreadStart也不起作用(带锁或不带锁)。我还检查过,一旦设置了myInterface(myInterface=iInterface),myInterface仍然可以“CallMethod”。跨线程对象访问并不总是自动导致问题。例如,对于只读访问,不需要锁定。2.关于最后一段,您不能将接口作为对象传递,因此即使将非null对象分配给具有接口(静态)类型的变量,并且代码已编译,也可以调用所有这些方法。将静态类型(接口)看作是另一种实现类型的某种外观。感谢您的回复。你的解释是有道理的,在MSDN上查找ComImport的免责条款似乎也是有道理的。干杯。这是我的荣幸:)我以前遇到过这个问题,这是一个需要尝试解决的噩梦,直到灯泡熄灭,我最终消耗了创建COM对象的线程中的COM对象。[+1]谢谢大家!对我来说,错误是[StatThread]丢失了。这个问题和答案让我在阅读线程问题后找到了它。ComImport和Guid就是它!为了使我的包装器单元可测试并隔离COM组件,我正在努力处理相同的强制转换异常(与线程无关)。谢谢你能解释一下变化吗?