简体   繁体   English

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

[英]Unable to cast COM object of type exception

I have the following code: 我有以下代码:

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

Which works fine. 哪个工作正常。 However, if I change the code to be threaded: 但是,如果我将代码更改为线程:

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

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

When i use the thread I receive the exception: 当我使用线程时,我收到异常:

Unable to cast COM object of type 'System.__ComObject' to interface type 'IMyInterface'. 无法将“System .__ ComObject”类型的COM对象强制转换为接口类型“IMyInterface”。 This operation failed because the QueryInterface call on the COM component for the interface with IID '{GUID}' failed due to the follow error: No such interface supported 此操作失败,因为对于具有IID“{GUID}”的接口的COM组件的QueryInterface调用由于以下错误而失败:不支持此类接口

But the interface should be supported just fine? 但是应该支持接口就好了吗? Anyone have any thoughts on what is going on here? 有人对这里发生的事情有任何想法吗?

This nasty, nasty exception arises because of a concept known as COM marshalling. 由于称为COM编组的概念,这种令人讨厌的,令人讨厌的例外产生了。 The essence of the problem lies in the fact that in order to consume COM objects from any thread, the thread must have access to the type information that describes the COM object. 问题的实质在于,为了从任何线程使用COM对象,线程必须能够访问描述COM对象的类型信息。

In your scenario described, the reason it fails on the second thread is because the second thread does not have type information for the interface. 在您描述的场景中,它在第二个线程上失败的原因是因为第二个线程没有该接口的类型信息。

You could try adding the following to your code: 您可以尝试在代码中添加以下内容:

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

Basically the declaration above instructs the .NET framework COM loader to load type information using traditional techniques from the registry and locate the associated type library and go from there. 基本上上面的声明指示.NET框架COM加载器使用注册表中的传统技术加载类型信息,并找到相关的类型库并从那里开始。

You should also restrict the creation of the COM object to a single thread (to prevent thread marshalling) to help solve this issue. 您还应该将COM对象的创建限制为单个线程(以防止线程编组)以帮助解决此问题。

To summarize, this error revolves around type information and thread marshalling. 总而言之,此错误围绕类型信息和线程编组。 Make sure that each thread that wants to access the COM object has the relevant information to unmarshal the object from the source thread. 确保要访问COM对象的每个线程都具有从源线程解组对象的相关信息。

PS: This problem is solved in .NET 4.0 using a technique called "Type Equivalence" PS:使用称为“类型等价”的技术在.NET 4.0中解决了这个问题

I got an advice and it helped me! 我得到了一个建议,它帮助了我!

Find in the main thread (Program.cs) the line [STAThread] and change it to [MTAThread]. 在主线程(Program.cs)中查找[STAThread]行并将其更改为[MTAThread]。

I've been developing a C# application which uses 7-zip through COM interfaces. 我一直在开发一个C#应用程序,它通过COM接口使用7-zip。 I ran into this funny thing where I was able to extract archives from a worker thread in one instance, but not another, getting this same exception. 我遇到了这个有趣的事情,我能够在一个实例中从工作线程中提取存档,而不是另一个,从而获得同样的异常。

I found that, so long as you initialize the offending COM object in the thread where it is used no exception is thrown. 我发现,只要你在使用它的线程中初始化有问题的COM对象,就不会抛出异常。 My solution was to dispose the objects which utilized COM interfaces and re-initialize them when passing them between threads. 我的解决方案是处理使用COM接口的对象,并在线程之间传递它们时重新初始化它们。

Well, for one, you are making a cross-thread call to an object without locking it, this automatically will cause some issues. 好吧,首先,你正在对一个对象进行跨线程调用而不锁定它,这会自动导致一些问题。 Your code should look more like: 您的代码看起来应该更像:

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 ( );
     }
}

From what I understand, the error you listed can sometimes occur when the resource cannot be accessed, which, with a cross-thread operation like this, would most likely happen. 根据我的理解,当无法访问资源时,有时会出现您列出的错误,这种情况很可能会发生,这样的跨线程操作。 Don't quote me on it though, I'm no COM expert. 不要引用我的话,我不是COM专家。

Truthfully, I don't think I would approach calling this method in this fashion, way too many risks in doing so. 说实话,我认为我不会以这种方式调用这种方法,这样做的风险太大了。 Have you considered using a ParameterizedThreadStart and passing the object through that way? 您是否考虑过使用ParameterizedThreadStart并通过这种方式传递对象? You'd still need to safely lock your objects for the cross-thread operations, but it would be safer. 您仍然需要安全地锁定对象以进行跨线程操作,但它会更安全。

Furthermore, check to make sure that your "myInterface" class can still call the "CallMethod()" method. 此外,请检查以确保您的“myInterface”类仍然可以调用“CallMethod()”方法。 Interfaces have no implementation, you may be running into problems when you set "myInterface = iInterface". 接口没有实现,当您设置“myInterface = iInterface”时可能会遇到问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 无法转换类型异常的对象 - Unable to cast object of type exception WatiN“无法转换COM对象”异常 - WatiN “Unable to cast COM object” exception 无法将COM对象强制转换为类类型 - Unable to cast COM Object to class type 在C#中加载COM对象抛出异常“无法将类型为'System .__ ComObject'的COM对象转换为接口类型...”,但C ++或VB没有 - Loading COM object in C# throws exception “Unable to cast COM object of type 'System.__ComObject' to interface type …”, but C++ or VB not 无效的强制转换异常,无法将COM对象强制转换为Excel - Invalid Cast Exception, Unable to Cast COM object to Excel C#异常-无法转换类型为COM的对象…该应用程序调用了一个编组为不同线程的接口 - C# exception - Unable to cast COM object of type… The application called an interface that was marshalled for a different thread nHibernate异常:无法转换类型的对象 - nHibernate Exception: Unable to cast object of type 无法投射 COM object - Unable to cast COM object 使用ExeCOMServer时,无法将类型为“...”的COM对象转换为接口类型“...” - Unable to cast COM object of type '…' to interface type '…' while using an ExeCOMServer InvalidCastException:无法将类型x的COM对象转换为接口类型y - InvalidCastException: Unable to cast COM object of type x to interface type y
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM